# Copyright (C) 2024 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Contains tables related to perf data ingestion.
"""

from python.generators.trace_processor_table.public import Column as C
from python.generators.trace_processor_table.public import ColumnDoc
from python.generators.trace_processor_table.public import ColumnFlag
from python.generators.trace_processor_table.public import CppAccess
from python.generators.trace_processor_table.public import CppInt64
from python.generators.trace_processor_table.public import CppOptional
from python.generators.trace_processor_table.public import CppString
from python.generators.trace_processor_table.public import CppTableId
from python.generators.trace_processor_table.public import CppUint32
from python.generators.trace_processor_table.public import Table
from python.generators.trace_processor_table.public import TableDoc

from src.trace_processor.tables.profiler_tables import STACK_PROFILE_FRAME_TABLE
from src.trace_processor.tables.profiler_tables import STACK_PROFILE_MAPPING_TABLE
from src.trace_processor.tables.metadata_tables import THREAD_TABLE
from src.trace_processor.tables.etm_tables import FILE_TABLE

SPE_RECORD_TABLE = Table(
    python_module=__file__,
    class_name='SpeRecordTable',
    sql_name='__intrinsic_spe_record',
    columns=[
        C('ts', CppInt64(), ColumnFlag.SORTED),
        C('utid', CppOptional(CppTableId(THREAD_TABLE))),
        C('exception_level', CppString()),
        C(
            'instruction_frame_id',
            CppOptional(CppTableId(STACK_PROFILE_FRAME_TABLE)),
        ),
        C('operation', CppString()),
        C('data_virtual_address', CppInt64()),
        C('data_physical_address', CppInt64()),
        C('total_latency', CppUint32()),
        C('issue_latency', CppUint32()),
        C('translation_latency', CppUint32()),
        C('events_bitmask', CppInt64()),
        C('data_source', CppString()),
    ],
    tabledoc=TableDoc(
        doc='''
          This table has a row for each sampled operation in an ARM Statistical
          Profiling Extension trace.
        ''',
        group='Perf',
        columns={
            'ts':
                'Time the operation was sampled',
            'utid':
                'EXecuting thread',
            'exception_level':
                'Exception level the operation executed in',
            'instruction_frame_id':
                ColumnDoc(
                    'Instruction virtual address',
                    joinable='stack_profile_frame.id'),
            'operation':
                'Operation executed',
            'data_virtual_address':
                'Virtual address of accesses data (if any)',
            'data_physical_address':
                '''
                  Physical address of accesses data (if any)
                ''',
            'total_latency':
                '''
                  Cycle count from the operation being dispatched for issue to
                  the operation being complete.
                ''',
            'issue_latency':
                '''
                  Cycle count from the operation being dispatched for issue to
                  the operation being issued for execution.
                ''',
            'translation_latency':
                '''
                  Cycle count from a virtual address being passed to the MMU for
                  translation to the result of the translation being available.
                ''',
            'events_bitmask':
                'Events generated by the operation',
            'data_source':
                '''
                  Where the data returned for a load operation was sourced
                ''',
        },
    ),
)

MMAP_RECORD = Table(
    python_module=__file__,
    class_name='MmapRecordTable',
    sql_name='__intrinsic_mmap_record',
    columns=[
        C(
            'ts',
            CppInt64(),
            cpp_access=CppAccess.READ,
        ),
        C('upid', CppOptional(CppUint32()), cpp_access=CppAccess.READ),
        C(
            'mapping_id',
            CppTableId(STACK_PROFILE_MAPPING_TABLE),
            cpp_access=CppAccess.READ,
        ),
        C(
            'file_id',
            CppOptional(CppTableId(FILE_TABLE)),
            cpp_access=CppAccess.READ,
        ),
    ],
    tabledoc=TableDoc(
        doc='''
          This table has a row for each mmap or mmap2 record in a perf trace.
          It allows us to determine when mappings are created, what process
          created them and what is the actual data contained in the mapping.
        ''',
        group='Perf',
        columns={
            'ts':
                'Time the mapping was created.',
            'upid':
                'Process that created the mapping',
            'mapping_id':
                ColumnDoc('Mapping', joinable='stack_profile_mapping.id'),
            'file_id':
                ColumnDoc(
                    'References a file that backs the contents of this mapping',
                    joinable='__intrinsic_file.id'),
        },
    ))

ALL_TABLES = [
    SPE_RECORD_TABLE,
    MMAP_RECORD,
]
