#!/usr/bin/env python3
# Copyright (C) 2021 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.

# This tool checks that every create (table|view) is prefixed by
# drop (table|view).

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import sys
from typing import Dict, Tuple, List

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(os.path.join(ROOT_DIR))

from python.generators.sql_processing.utils import check_banned_create_table_as
from python.generators.sql_processing.utils import check_banned_create_view_as
from python.generators.sql_processing.utils import check_banned_words
from python.generators.sql_processing.utils import match_pattern
from python.generators.sql_processing.utils import DROP_TABLE_VIEW_PATTERN
from python.generators.sql_processing.utils import CREATE_TABLE_VIEW_PATTERN

# Allowlist path are relative to the metrics root.
CREATE_TABLE_ALLOWLIST = {
    ('/android'
     '/android_blocking_calls_cuj_metric.sql'): [
        'android_cujs', 'relevant_binder_calls_with_names',
        'android_blocking_calls_cuj_calls'
    ],
    ('/android'
    '/android_blocking_calls_unagg.sql'): [
        'filtered_processes_with_non_zero_blocking_calls',
        'process_info', 'android_blocking_calls_unagg_calls'
    ],
    '/android/jank/cujs.sql': ['android_jank_cuj'],
    '/chrome/gesture_flow_event.sql': [
        '{{prefix}}_latency_info_flow_step_filtered'
    ],
    '/chrome/gesture_jank.sql': [
        '{{prefix}}_jank_maybe_null_prev_and_next_without_precompute'
    ],
    '/experimental/frame_times.sql': ['DisplayCompositorPresentationEvents'],
}


def match_create_table_pattern_to_dict(
    sql: str, pattern: str) -> Dict[str, Tuple[int, str]]:
  res = {}
  for line_num, matches in match_pattern(pattern, sql).items():
    res[matches[3]] = [line_num, str(matches[2])]
  return res


def match_drop_view_pattern_to_dict(sql: str,
                                    pattern: str) -> Dict[str, Tuple[int, str]]:
  res = {}
  for line_num, matches in match_pattern(pattern, sql).items():
    res[matches[1]] = [line_num, str(matches[0])]
  return res


def check(path: str, metrics_sources: str) -> List[str]:
  with open(path) as f:
    sql = f.read()

  # Check that each function/macro is using "CREATE OR REPLACE"
  lines = [l.strip() for l in sql.split('\n')]
  for line in lines:
    if line.startswith('--'):
      continue
    if 'create perfetto function' in line.casefold():
      errors.append(
          f'Use "CREATE OR REPLACE PERFETTO FUNCTION" in Perfetto metrics, '
          f'to prevent the file from crashing if the metric is rerun.\n'
          f'Offending file: {path}\n')
    if 'create perfetto macro' in line.casefold():
      errors.append(
          f'Use "CREATE OR REPLACE PERFETTO MACRO" in Perfetto metrics, to '
          f'prevent the file from crashing if the metric is rerun.\n'
          f'Offending file: {path}\n')



  # Check that CREATE VIEW/TABLE has a matching DROP VIEW/TABLE before it.
  create_table_view_dir = match_create_table_pattern_to_dict(
      sql, CREATE_TABLE_VIEW_PATTERN)
  drop_table_view_dir = match_drop_view_pattern_to_dict(
      sql, DROP_TABLE_VIEW_PATTERN)
  errors = check_banned_create_table_as(sql,
                                        path.split(ROOT_DIR)[1],
                                        metrics_sources.split(ROOT_DIR)[1],
                                        CREATE_TABLE_ALLOWLIST)
  errors += check_banned_create_view_as(sql, path.split(ROOT_DIR)[1])
  for name, [line, type] in create_table_view_dir.items():
    if name not in drop_table_view_dir:
      errors.append(f'Missing DROP before CREATE {type.upper()} "{name}"\n'
                    f'Offending file: {path}\n')
      continue
    drop_line, drop_type = drop_table_view_dir[name]
    if drop_line > line:
      errors.append(f'DROP has to be before CREATE {type.upper()} "{name}"\n'
                    f'Offending file: {path}\n')
      continue
    if drop_type != type:
      errors.append(f'DROP type doesnt match CREATE {type.upper()} "{name}"\n'
                    f'Offending file: {path}\n')

  errors += check_banned_words(sql, path)
  return errors


def main():
  errors = []
  metrics_sources = os.path.join(ROOT_DIR, 'src', 'trace_processor', 'metrics',
                                 'sql')
  for root, _, files in os.walk(metrics_sources, topdown=True):
    for f in files:
      path = os.path.join(root, f)
      if path.endswith('.sql'):
        errors += check(path, metrics_sources)

  if errors:
    sys.stderr.write("\n".join(errors))
    sys.stderr.write("\n")
  return 0 if not errors else 1


if __name__ == '__main__':
  sys.exit(main())
