#!/usr/bin/env python3
#
# Copyright 2021 The Cobalt Authors. All Rights Reserved.
#
# 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.
"""Formats ninja compilation databases to be easily diffed against each other.

Primarily used for looking at the differences between GYP and GN builds during
the GN migration.

To test, first generate a the ninja build files, then use

ninja -t compdb > out.json

in the build directory to generate a JSON file containing all actions ninja
would run. The run this script on that file and diff it with another.
"""

import argparse
import json
import os

from typing import List, Tuple

_ACTION_COMPONENTS = ['directory', 'command', 'file', 'output']


def make_path_absolute(path: str, directory: str) -> str:
  if os.path.isabs(path):
    return path

  return os.path.normpath(os.path.join(directory, path))


def remove_directory_path(path: str, directory: str) -> str:
  if os.path.commonpath([path, directory]) != directory:
    return path

  return os.path.relpath(path, directory)


def normalize_if_pathlike(path: str, directory: str) -> str:
  absolute_path = make_path_absolute(path, directory)
  if os.path.exists(absolute_path):
    return remove_directory_path(absolute_path, directory)
  return path


def relativize_path(path: str, directory: str) -> str:
  path = make_path_absolute(path, directory)
  return remove_directory_path(path, directory)


def validate_json_database(json_content: object):
  for entry in json_content:
    for component in _ACTION_COMPONENTS:
      if component not in entry:
        raise ValueError(f'Ninja json entry is missing {component} field.')


def normalize_command(command: str, directory: str) -> Tuple[List[str], object]:
  command_list = command.split()
  command_with_normalized_paths = [
      normalize_if_pathlike(e, directory) for e in command_list
  ]

  # command_parser = argparse.ArgumentParser()
  # command_parser.add_argument('-x', type=str)
  # command_parser.add_argument('-MF', type=str)
  # command_parser.add_argument('-o', type=str)
  # command_parser.add_argument('-c', type=str)
  # parsed, unknown = command_parser.parse_known_args(
  #     command_with_normalized_paths)
  # return (parsed, sorted(unknown, reverse=True))
  return sorted(command_with_normalized_paths, reverse=True)


def normalize_all_paths(json_content: List[object]) -> List[object]:
  for entry in json_content:
    directory = entry['directory']
    command = normalize_command(entry['command'], directory)
    file_entry = relativize_path(entry['file'], directory)
    output_entry = entry['output']
    yield {'command': command, 'file': file_entry, 'output': output_entry}


def normalize_json_file(filename: str) -> List[object]:
  with open(filename) as f:
    content = json.load(f)

  validate_json_database(content)
  normalized_content = normalize_all_paths(content)
  return sorted(normalized_content, key=lambda x: x['output'])


def main(json_database: str, output_filename: str):
  json_content = normalize_json_file(json_database)
  with open(output_filename, 'w') as f:
    json.dump(json_content, f, indent=4, sort_keys=True)


if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  parser.add_argument('json_filename', type=str)
  parser.add_argument('-o', '--output', type=str)
  args = parser.parse_args()
  output = args.output if args.output else 'normalized_' + os.path.basename(
      args.json_filename)
  main(args.json_filename, output)
