# Copyright 2023 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unittests for remoteexec_lib.py"""

import datetime
import getpass
import gzip
import json
import os
from pathlib import Path
import time

from chromite.lib import cros_test_lib
from chromite.lib import osutils
from chromite.lib import remoteexec_lib
from chromite.utils import hostname_util


class TestLogArchiver(cros_test_lib.MockTempDirTestCase):
    """Tests for remoteexec_lib."""

    def setUp(self) -> None:
        self.src_dir = self.tempdir / "remoteexec_src_dir"
        self.dest_dir = self.tempdir / "remoteexec_dest_dir"

        osutils.SafeMakedirs(self.src_dir)
        osutils.SafeMakedirs(self.dest_dir)

        self.archiver = remoteexec_lib.LogsArchiver(self.src_dir, self.dest_dir)
        self.archiver.remoteexec_log_dir_for_testing = self.src_dir

    def _create_file(self, package_name: str, filename: str) -> Path:
        path = self.src_dir / f"reclient-{package_name}" / filename
        osutils.WriteFile(
            path,
            f"Package: {package_name}\nFile: {filename}",
            makedirs=True,
        )
        return path

    def testArchiveFiles(self) -> None:
        """Test LogArchiver.Archive() method."""
        interesting_log_files = [
            self._create_file("chromeos-chrome", "test.INFO.log"),
            self._create_file("chromeos-chrome", "reproxy_test.INFO"),
            self._create_file("chromeos-chrome", "reproxy_test.rrpl"),
        ]
        uninteresting_log_files = [
            self._create_file("chromeos-chrome", "test.INFO"),
        ]

        archive_files = self.archiver.archive_remoteexec_logs()

        self.assertEqual(
            archive_files,
            [
                "reclient-chromeos-chrome/test.INFO.log.gz",
                "reclient-chromeos-chrome/reproxy_test.INFO.gz",
                "reclient-chromeos-chrome/reproxy_test.rrpl.gz",
            ],
        )

        for file in archive_files:
            self.assertExists(self.dest_dir / file)

        for file in interesting_log_files:
            self.assertNotExists(file)

        for file in uninteresting_log_files:
            self.assertExists(file)

    def testNinjaLogArchive(self) -> None:
        """Test successful archive of ninja logs."""
        ninja_log_path = os.path.join(self.src_dir, "ninja_log")
        osutils.WriteFile(ninja_log_path, "Ninja Log Content\n")
        timestamp = datetime.datetime(2024, 4, 1, 12, 0, 0)
        mtime = time.mktime(timestamp.timetuple())
        os.utime(ninja_log_path, ((time.time(), mtime)))

        osutils.WriteFile(
            os.path.join(self.src_dir, "ninja_command"), "ninja_command"
        )
        osutils.WriteFile(os.path.join(self.src_dir, "ninja_cwd"), "ninja_cwd")
        osutils.WriteFile(
            os.path.join(self.src_dir, "ninja_env"),
            "key1=value1\0key2=value2\0",
        )
        osutils.WriteFile(os.path.join(self.src_dir, "ninja_exit"), "0")

        archived_results = self.archiver.archive_ninja_log()

        username = getpass.getuser()
        pid = os.getpid()
        hostname = hostname_util.get_host_name()
        ninjalog_filename = "ninja_log.%s.%s.20240401-120000.%d.gz" % (
            username,
            hostname,
            pid,
        )
        # Verify the archived files in the dest_dir
        archived_dir_files = os.listdir(self.dest_dir)
        self.assertCountEqual(
            archived_dir_files,
            [
                ninjalog_filename,
            ],
        )
        # Verify the archived_tuple result.
        self.assertEqual(
            archived_results,
            [
                ninjalog_filename,
            ],
        )

        # Verify content of ninja_log file.
        ninjalog_path = os.path.join(self.dest_dir, ninjalog_filename)

        with gzip.open(ninjalog_path, "rt", encoding="utf-8") as gzip_file:
            ninja_log_content = gzip_file.read()

        content, eof, metadata_json = ninja_log_content.split("\n", 3)
        self.assertEqual("Ninja Log Content", content)
        self.assertEqual("# end of ninja log", eof)
        metadata = json.loads(metadata_json)
        self.assertEqual(
            metadata,
            {
                "platform": "chromeos",
                "cmdline": ["ninja_command"],
                "cwd": "ninja_cwd",
                "exit": 0,
                "env": {"key1": "value1", "key2": "value2"},
            },
        )
