#!/usr/bin/env fuchsia-vendored-python
# Copyright 2021 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unit test for main.py.

To manually run this test:
  fuchsia-vendored-python main_test.py
"""
import json
import os
import subprocess
import tempfile
import time
import unittest
import unittest.mock as mock

from typing import Any

import main

_TARGET_1 = "foo.cc.o"
_TARGET_2 = "baz/bar.cc.o"
_TARGET_3 = "biz/fuzz.cc.o"
_TARGETS = [_TARGET_1, _TARGET_2, _TARGET_3]


def setup_compdb_and_fs(
    directory: str, targets: list[str], changed: list[str]
) -> tuple[list[dict[str, str]], list[dict[str, str]]]:
    compdb = []
    changed_comp_db = []
    # Setup targets
    for target in targets:
        if not target.endswith(".o"):
            raise Exception(
                "Expected all targets to end with '.o', "
                "but received %s." % (target)
            )

        # Add the target to the compdb
        target_def = {
            "file": target[:-2],
            "directory": directory,
            "command": "clang++ -o %s" % (target),
        }
        compdb.append(target_def)

        # If it is expected to change, add the target to the changed compdb
        if target in changed:
            changed_comp_db.append(target_def)

        # Make the placeholder file to set the last modified time before fx ninja
        target_path = os.path.join(directory, target)
        os.makedirs(os.path.dirname(target_path), exist_ok=True)
        with open(target_path, "w") as f:
            f.write("test placeholder")

    return (compdb, changed_comp_db)


class RunCsaHelperTest(unittest.TestCase):
    def helper(
        self, temp_dir: str, targets: list[str], changed: list[str]
    ) -> None:
        ninja_path = "tmp/ninja"
        out_dir = os.path.join(temp_dir, "foo/bar")

        # Set up the output directory and compdbs
        compdb, expected_changed_compdb = setup_compdb_and_fs(
            out_dir, targets, changed
        )

        # Write the compdb
        input_file = os.path.join(temp_dir, "compile_commands.json")
        with open(input_file, "w") as in_file:
            json.dump(compdb, in_file)

        # Mock out the xargs fx ninja call
        fake_ninja = FakeNinja(out_dir, changed)
        with mock.patch("subprocess.run") as mock_run:
            mock_run.side_effect = fake_ninja.run

            output_file = os.path.join(
                temp_dir, "modified_compile_commands.json"
            )
            args = [
                "--input",
                input_file,
                "--output",
                output_file,
                "--ninja",
                ninja_path,
            ]

            # Ensure the script succeeded
            self.assertEqual(0, main.main(args))

            # Check that the output compdb contains the files that were modified
            with open(output_file, "r") as out_file:
                self.assertEqual(
                    json.dumps(expected_changed_compdb, indent=2),
                    out_file.read(),
                )

    def test_no_changed_files(self) -> None:
        with tempfile.TemporaryDirectory() as temp_dir:
            self.helper(temp_dir, _TARGETS, [])

    def test_some_changed_files(self) -> None:
        with tempfile.TemporaryDirectory() as temp_dir:
            self.helper(temp_dir, _TARGETS, [_TARGET_1, _TARGET_3])

    def test_all_changed_files(self) -> None:
        with tempfile.TemporaryDirectory() as temp_dir:
            self.helper(temp_dir, _TARGETS, [_TARGET_1, _TARGET_2, _TARGET_3])


class FakeNinja(object):
    def __init__(self, directory: str, files_to_update: list[str]) -> None:
        self.directory = directory
        self.files_to_update = files_to_update
        return

    def run(
        self, *argv: Any, **kwargs: Any
    ) -> subprocess.CompletedProcess[bytes]:
        del argv
        del kwargs

        # Sleep for a second so that the modified time check changes
        time.sleep(1)

        for file_to_update in self.files_to_update:
            target_path = os.path.join(self.directory, file_to_update)
            if not os.path.exists(target_path):
                raise Exception(
                    "Expected path %s to already exist." % (target_path)
                )
            with open(target_path, "w") as f:
                f.write("updated")

        return subprocess.CompletedProcess(args=[], returncode=0, stdout=b"")


if __name__ == "__main__":
    unittest.main()
