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

import multiprocessing
import os
import signal
import sys
import time
from typing import Any, Dict, IO, List

from google.protobuf import descriptor_pb2, message_factory
from python.generators.diff_tests import models

# PID of the main process, used to distinguish from forked workers
_main_pid = None


class ProtoManager:
  """A helper class for all proto related tasks."""

  def __init__(self, descriptor_file_paths: List[str]):
    files = []
    for file_path in descriptor_file_paths:
      files.extend(self.read_descriptor(file_path).file)
    self.messages = message_factory.GetMessages(files)

  def read_descriptor(self, file_name: str) -> descriptor_pb2.FileDescriptorSet:
    """Reads a file descriptor set from a file."""
    with open(file_name, 'rb') as f:
      contents = f.read()

    descriptor = descriptor_pb2.FileDescriptorSet()
    descriptor.MergeFromString(contents)

    return descriptor

  def create_message(self, proto_type: str) -> Any:
    return self.messages[proto_type]


USE_COLOR_CODES = sys.stderr.isatty()


class ColorFormatter:
  """A helper class for color formatting in the terminal."""

  def __init__(self, no_colors: bool):
    self.no_colors = no_colors

  def __red_str(self) -> str:
    return "\u001b[31m" if USE_COLOR_CODES and not self.no_colors else ""

  def __green_str(self) -> str:
    return "\u001b[32m" if USE_COLOR_CODES and not self.no_colors else ""

  def __yellow_str(self) -> str:
    return "\u001b[33m" if USE_COLOR_CODES and not self.no_colors else ""

  def __end_color(self) -> str:
    return "\u001b[0m" if USE_COLOR_CODES and not self.no_colors else ""

  def red(self, s: str) -> str:
    return self.__red_str() + s + self.__end_color()

  def green(self, s: str) -> str:
    return self.__green_str() + s + self.__end_color()

  def yellow(self, s: str) -> str:
    return self.__yellow_str() + s + self.__end_color()


def get_env(root_dir: str) -> Dict[str, str]:
  """Returns the environment variables for running trace_processor."""
  env = {
      'PERFETTO_BINARY_PATH': os.path.join(root_dir, 'test', 'data'),
      'PATH': os.environ['PATH'],
  }
  if sys.platform.startswith('linux'):
    env['PATH'] = os.path.join(root_dir, 'buildtools', 'linux64', 'clang',
                               'bin') + ':' + env['PATH']
  elif sys.platform.startswith('darwin'):
    # Sadly, on macOS we need to check out the Android deps to get
    # llvm symbolizer.
    env['PATH'] = os.path.join(root_dir, 'buildtools', 'ndk', 'toolchains',
                               'llvm', 'prebuilt', 'darwin-x86_64',
                               'bin') + ':' + env['PATH']
  elif sys.platform.startswith('win32'):
    env['PATH'] = os.path.join(root_dir, 'buildtools', 'win', 'clang',
                               'bin') + ';' + env['PATH']
  return env


def ctrl_c_handler(_num: int, _frame: Any):
  """Handles Ctrl+C by waiting for child processes to exit, then exiting.

  When Ctrl+C is pressed, the terminal sends SIGINT to the entire foreground
  process group. Child processes (executor workers, trace_processor_shell)
  receive SIGINT directly and will terminate. We just wait for them to finish,
  then exit cleanly.
  """
  global _main_pid

  # Child processes just exit silently
  if _main_pid is not None and os.getpid() != _main_pid:
    os._exit(0)

  # Main process: print message and wait for children to exit
  os.write(sys.stderr.fileno(), b'\nShutting down...\n')

  # Wait for child processes to terminate (they got SIGINT too)
  deadline = time.time() + 3.0
  while time.time() < deadline:
    if not multiprocessing.active_children():
      break
    time.sleep(0.01)

  # If any children are still alive after timeout, kill them
  for child in multiprocessing.active_children():
    child.kill()

  os._exit(0)


def setup_ctrl_c_handler():
  """Sets up Ctrl+C handler. Must be called once at start of main()."""
  global _main_pid
  _main_pid = os.getpid()
  signal.signal(signal.SIGINT, ctrl_c_handler)


def serialize_textproto_trace(trace_descriptor_path: str,
                              extension_descriptor_paths: List[str],
                              text_proto_path: str, out_stream: IO[bytes]):
  from python.generators.diff_tests.trace_generator import TraceGenerator
  TraceGenerator(trace_descriptor_path,
                 extension_descriptor_paths).serialize_textproto_trace(
                     text_proto_path, out_stream)


def serialize_python_trace(root_dir: str, trace_descriptor_path: str,
                           extension_descriptor_paths: List[str],
                           python_trace_path: str, out_stream: IO[bytes]):
  from python.generators.diff_tests.trace_generator import TraceGenerator
  TraceGenerator(trace_descriptor_path,
                 extension_descriptor_paths).serialize_python_trace(
                     root_dir, python_trace_path, out_stream)


def get_trace_descriptor_path(out_path: str, trace_descriptor: str):
  """Returns the path to the trace descriptor."""
  if trace_descriptor:
    return trace_descriptor

  path = ['gen', 'protos', 'perfetto', 'trace', 'trace.descriptor']
  trace_descriptor_path = os.path.join(out_path, *path)
  if not os.path.exists(trace_descriptor_path):
    trace_descriptor_path = os.path.join(out_path, 'gcc_like_host', *path)

  return trace_descriptor_path


def read_all_tests(name_filter: str,
                   root_dir: os.PathLike) -> List[models.TestCase]:
  """Reads all diff tests from the given directory."""
  from python.generators.diff_tests.test_loader import TestLoader
  return TestLoader(root_dir).discover_and_load_tests(name_filter)


def write_diff(expected: str, actual: str) -> str:
  """Returns a unified diff of the two strings."""
  import difflib
  expected_lines = expected.splitlines(True)
  actual_lines = actual.splitlines(True)
  diff = difflib.unified_diff(
      expected_lines, actual_lines, fromfile='expected', tofile='actual')
  return "".join(list(diff))
