#!/usr/bin/env python3

# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

import unittest
from unittest.mock import (
    MagicMock,
    patch,
)
from pathlib import Path
from io import BytesIO

import functest_coverage


class AnyStringWith(str):

    def __eq__(self, other):
        return self in other


class TestFunc(unittest.TestCase):

    def test_handle_libs(self):
        device_libs_all = [
            "//foo/a", "//foo/b_on_host_do_not", "//foo/c_on_host", "//foo/d"
        ]
        device_libs = ["//foo/a", "//foo/d"]

        self.assertEqual(functest_coverage.handle_libs(device_libs_all),
                         device_libs)

    @patch("functest_coverage.LLD_TARGET", "<lld_target>")
    @patch("functest_coverage.run")
    def test_handle_objs(self, mock_run):
        merged_library = Path("/foo/merged.so")
        obj_files = ["//foo/a.o", "//foo/d.o"]

        functest_coverage.handle_objs(merged_library, obj_files)

        mock_run.assert_called_once_with("<lld_target>",
                                         AnyStringWith("unresolved"),
                                         "-zmuldefs", "-o",
                                         str(merged_library), *obj_files)

    @patch("functest_coverage.run")
    def test_handle_test_targets(self, mock_run):
        test_targets = [
            "//foo/test", "//bar/test_cw310_test_rom",
            "//qux/long_wycheproof_test"
        ]
        mock_run.side_effect = (
            None,
            ["workspace_path"],
            ["bitstream_file.bit"],
            None,
        )

        res = functest_coverage.handle_test_targets(test_targets)

        self.assertEqual(res, ["//bar/test_cw310_test_rom"])
        calls_mock_run = mock_run.call_args_list
        self.assertEqual(len(calls_mock_run), 4)
        self.assertEqual(calls_mock_run[0][0],
                         (functest_coverage.BAZEL, "build",
                          functest_coverage.BITSTREAM_TARGET))
        self.assertEqual(calls_mock_run[1][0],
                         (functest_coverage.BAZEL, "info", "workspace"))
        self.assertEqual(
            calls_mock_run[2][0],
            (functest_coverage.BAZEL, "cquery", "--output=starlark",
             "--starlark:expr", "target.files.to_list()[0].path",
             functest_coverage.BITSTREAM_TARGET))
        self.assertEqual(
            calls_mock_run[3][0],
            (functest_coverage.BAZEL, "run", "//sw/host/opentitantool", "--",
             "fpga", "load-bitstream", "workspace_path/bitstream_file.bit"))

    def mock_binary_file(self: unittest.TestCase,
                         name: str,
                         contents: bytes = None) -> MagicMock:
        mock_file = MagicMock(autospec=BytesIO)
        mock_file.__enter__.side_effect = [mock_file]
        mock_file.name = name
        if contents:
            mock_file.read.side_effect = [contents]
        return mock_file

    @patch("pathlib.Path.open", autospec=True)
    @patch("functest_coverage.extract_profile_data")
    @patch("pathlib.Path.__truediv__",
           side_effect=Path.__truediv__,
           autospec=True)
    def test_handle_test_log_dirs(self, mock_path_div,
                                  mock_extract_profile_data, mock_path_open):
        test_log_dirs = [Path("/testlogs/foo"), Path("/testlogs/bar")]
        test_logs = [
            Path("/testlogs/foo/test.log"),
            Path("/testlogs/bar/test.log")
        ]
        profiles = [
            Path("/testlogs/foo/prof.raw"),
            Path("/testlogs/bar/prof.raw")
        ]

        mock_files = [
            self.mock_binary_file(name=test_logs[0], contents=b"<log_0>"),
            self.mock_binary_file(name=profiles[0]),
            self.mock_binary_file(name=test_logs[1], contents=b"<log_1>"),
            self.mock_binary_file(name=profiles[1]),
        ]
        mock_path_open.side_effect = mock_files
        mock_extract_profile_data.side_effect = (b"<raw_profile_0>",
                                                 b"<raw_profile_1>")

        self.assertEqual(functest_coverage.handle_test_log_dirs(test_log_dirs),
                         profiles)

        calls_path_div = mock_path_div.call_args_list
        self.assertEqual(len(calls_path_div), 4)
        self.assertEqual(calls_path_div[0][0], (test_log_dirs[0], "test.log"))
        self.assertEqual(calls_path_div[1][0], (test_log_dirs[0], "prof.raw"))
        self.assertEqual(calls_path_div[2][0], (test_log_dirs[1], "test.log"))
        self.assertEqual(calls_path_div[3][0], (test_log_dirs[1], "prof.raw"))

        calls_path_open = mock_path_open.call_args_list
        self.assertEqual(len(calls_path_open), 4)
        self.assertEqual(calls_path_open[0][0], (test_logs[0], "rb"))
        self.assertEqual(calls_path_open[1][0], (profiles[0], "wb"))
        self.assertEqual(calls_path_open[2][0], (test_logs[1], "rb"))
        self.assertEqual(calls_path_open[3][0], (profiles[1], "wb"))

        calls_extract_profile_data = mock_extract_profile_data.call_args_list
        self.assertEqual(len(calls_extract_profile_data), 2)
        self.assertEqual(calls_extract_profile_data[0][0], ("<log_0>", ))
        self.assertEqual(calls_extract_profile_data[1][0], ("<log_1>", ))

        mock_files[1].write.assert_called_once_with(b"<raw_profile_0>")
        mock_files[3].write.assert_called_once_with(b"<raw_profile_1>")

    def test_params(self):
        self.assertEqual(functest_coverage.PARAMS.bazel_test_type,
                         AnyStringWith("sh_test"))
        self.assertEqual(functest_coverage.PARAMS.config,
                         "ot_coverage_on_target")
        self.assertEqual(functest_coverage.PARAMS.libs_fn,
                         functest_coverage.handle_libs)
        self.assertEqual(functest_coverage.PARAMS.objs_fn,
                         functest_coverage.handle_objs)
        self.assertEqual(functest_coverage.PARAMS.test_targets_fn,
                         functest_coverage.handle_test_targets)
        self.assertEqual(functest_coverage.PARAMS.test_log_dirs_fn,
                         functest_coverage.handle_test_log_dirs)
        self.assertEqual(functest_coverage.PARAMS.report_title,
                         AnyStringWith("Functional Test"))


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