#!/usr/bin/env python3
# Copyright (c) 2023 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import datetime
import hashlib
import os
import os.path
import sys
import time
import unittest
import unittest.mock

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, ROOT_DIR)

import gclient_paths
import ninja_reclient
import reclient_helper
from testing_support import trial_dir


def write(filename, content):
    """Writes the content of a file and create the directories as needed."""
    filename = os.path.abspath(filename)
    dirname = os.path.dirname(filename)
    if not os.path.isdir(dirname):
        os.makedirs(dirname)
    with open(filename, 'w') as f:
        f.write(content)


class NinjaReclientTest(trial_dir.TestCase):
    def setUp(self):
        super(NinjaReclientTest, self).setUp()
        self.previous_dir = os.getcwd()
        os.chdir(self.root_dir)

    def tearDown(self):
        os.chdir(self.previous_dir)
        super(NinjaReclientTest, self).tearDown()

    @unittest.mock.patch.dict(os.environ,
                              {'AUTONINJA_BUILD_ID': "SOME_RANDOM_ID"},
                              clear=True)
    @unittest.mock.patch('reclient_helper.datetime_now',
                         return_value=datetime.datetime(2017, 3, 16, 20, 0, 41,
                                                        0))
    @unittest.mock.patch('subprocess.call', return_value=0)
    @unittest.mock.patch('ninja.main', return_value=0)
    @unittest.mock.patch('reclient_metrics.check_status', return_value=False)
    def test_ninja_reclient_sets_path_env_vars(self, *_):
        reclient_bin_dir = os.path.join('src', 'buildtools', 'reclient')
        reclient_cfg = os.path.join('src', 'buildtools', 'reclient_cfgs',
                                    'reproxy.cfg')
        write('.gclient', '')
        write('.gclient_entries', 'entries = {"buildtools": "..."}')
        write(os.path.join(reclient_bin_dir, 'version.txt'), '0.0')
        write(reclient_cfg, '0.0')
        argv = ["ninja_reclient.py", "-C", "out/a", "chrome"]

        self.assertEqual(0, ninja_reclient.main(argv))

        run_log_dir = os.path.join(self.root_dir, "out", "a", ".reproxy_tmp",
                                   "logs",
                                   "20170316T200041.000000_SOME_RANDOM_ID")

        self.assertTrue(
            os.path.isdir(
                os.path.join(self.root_dir, "out", "a", ".reproxy_tmp")))
        self.assertTrue(
            os.path.isdir(
                os.path.join(
                    self.root_dir, ".reproxy_cache",
                    hashlib.md5(
                        os.path.join(self.root_dir, "out", "a",
                                     ".reproxy_tmp").encode()).hexdigest())))
        self.assertTrue(os.path.isdir(run_log_dir))
        self.assertEqual(os.environ.get('RBE_output_dir'), run_log_dir)
        self.assertEqual(os.environ.get('RBE_proxy_log_dir'), run_log_dir)
        self.assertEqual(
            os.environ.get('RBE_cache_dir'),
            os.path.join(
                self.root_dir, ".reproxy_cache",
                hashlib.md5(
                    os.path.join(self.root_dir, "out", "a",
                                 ".reproxy_tmp").encode()).hexdigest()))
        if sys.platform.startswith('win'):
            self.assertEqual(
                os.environ.get('RBE_server_address'),
                "pipe://%s/reproxy.pipe" % hashlib.sha256(
                    os.path.join(self.root_dir, "out", "a", ".reproxy_tmp",
                                 "logs", "20170316T200041.000000_SOME_RANDOM_ID"
                                 ).encode()).hexdigest())
        else:
            self.assertEqual(
                os.environ.get('RBE_server_address'),
                "unix:///tmp/reproxy_%s.sock" % hashlib.sha256(
                    os.path.join(self.root_dir, "out", "a", ".reproxy_tmp",
                                 "logs", "20170316T200041.000000_SOME_RANDOM_ID"
                                 ).encode()).hexdigest())

    @unittest.mock.patch('subprocess.call', return_value=0)
    @unittest.mock.patch('ninja.main', return_value=0)
    @unittest.mock.patch('reclient_metrics.check_status', return_value=False)
    def test_ninja_reclient_calls_reclient_binaries(self, mock_metrics_status,
                                                    mock_ninja, mock_call):
        reclient_bin_dir = os.path.join('src', 'buildtools', 'reclient')
        reclient_cfg = os.path.join('src', 'buildtools', 'reclient_cfgs',
                                    'reproxy.cfg')
        write('.gclient', '')
        write('.gclient_entries', 'entries = {"buildtools": "..."}')
        write(os.path.join(reclient_bin_dir, 'version.txt'), '0.0')
        write(reclient_cfg, '0.0')
        argv = ["ninja_reclient.py", "-C", "out/a", "chrome"]

        self.assertEqual(0, ninja_reclient.main(argv))

        mock_metrics_status.assert_called_once_with("out/a")
        mock_ninja.assert_called_once_with(argv)
        mock_call.assert_has_calls([
            unittest.mock.call([
                os.path.join(self.root_dir, reclient_bin_dir,
                             'bootstrap' + gclient_paths.GetExeSuffix()),
                "--re_proxy=" +
                os.path.join(self.root_dir, reclient_bin_dir,
                             'reproxy' + gclient_paths.GetExeSuffix()),
                "--cfg=" + os.path.join(self.root_dir, reclient_cfg)
            ]),
            unittest.mock.call([
                os.path.join(self.root_dir, reclient_bin_dir,
                             'bootstrap' + gclient_paths.GetExeSuffix()),
                "--shutdown",
                "--cfg=" + os.path.join(self.root_dir, reclient_cfg)
            ]),
        ])

    @unittest.mock.patch.dict(os.environ,
                              {'AUTONINJA_BUILD_ID': "SOME_RANDOM_ID"})
    @unittest.mock.patch('subprocess.call', return_value=0)
    @unittest.mock.patch('ninja.main', return_value=0)
    @unittest.mock.patch('reclient_metrics.check_status', return_value=True)
    def test_ninja_reclient_collect_metrics_cache_missing(
            self, mock_metrics_status, *_):
        reclient_bin_dir = os.path.join('src', 'buildtools', 'reclient')
        reclient_cfg = os.path.join('src', 'buildtools', 'reclient_cfgs',
                                    'reproxy.cfg')
        write('.gclient', '')
        write('.gclient_entries', 'entries = {"buildtools": "..."}')
        write(os.path.join(reclient_bin_dir, 'version.txt'), '0.0')
        write(reclient_cfg, '0.0')
        argv = ["ninja_reclient.py", "-C", "out/a", "chrome"]

        self.assertEqual(0, ninja_reclient.main(argv))

        self.assertIn("/SOME_RANDOM_ID", os.environ["RBE_invocation_id"])
        self.assertEqual(os.environ.get('RBE_metrics_project'),
                         "chromium-reclient-metrics")
        self.assertEqual(os.environ.get('RBE_metrics_table'),
                         "rbe_metrics.builds")
        self.assertEqual(
            os.environ.get('RBE_metrics_labels'),
            "source=developer,tool=ninja_reclient,"
            "creds_cache_status=missing,creds_cache_mechanism=UNSPECIFIED")
        self.assertEqual(os.environ.get('RBE_metrics_prefix'),
                         "go.chromium.org")

        mock_metrics_status.assert_called_once_with("out/a")

    @unittest.mock.patch.dict(os.environ,
                              {'AUTONINJA_BUILD_ID': "SOME_RANDOM_ID"},
                              clear=True)
    @unittest.mock.patch('reclient_helper.datetime_now',
                         return_value=datetime.datetime(2017, 3, 16, 20, 0, 41,
                                                        0))
    @unittest.mock.patch('subprocess.call', return_value=0)
    @unittest.mock.patch('ninja.main', return_value=0)
    @unittest.mock.patch('reclient_metrics.check_status', return_value=True)
    def test_ninja_reclient_collect_metrics_cache_valid(self,
                                                        mock_metrics_status,
                                                        *_):
        reclient_bin_dir = os.path.join('src', 'buildtools', 'reclient')
        reclient_cfg = os.path.join('src', 'buildtools', 'reclient_cfgs',
                                    'reproxy.cfg')
        cache_dir = os.path.join(
            self.root_dir, ".reproxy_cache",
            hashlib.md5(
                os.path.join(self.root_dir, "out", "a",
                             ".reproxy_tmp").encode()).hexdigest())
        write('.gclient', '')
        write('.gclient_entries', 'entries = {"buildtools": "..."}')
        write(os.path.join(reclient_bin_dir, 'version.txt'), '0.0')
        write(reclient_cfg, '0.0')
        write(
            os.path.join(cache_dir, "reproxy.creds"), """
mechanism:  GCLOUD
expiry:  {
  seconds:  %d
}
              """ % (int(time.time()) + 10 * 60))
        argv = ["ninja_reclient.py", "-C", "out/a", "chrome"]

        self.assertEqual(0, ninja_reclient.main(argv))

        self.assertIn("/SOME_RANDOM_ID", os.environ["RBE_invocation_id"])
        self.assertEqual(os.environ.get('RBE_metrics_project'),
                         "chromium-reclient-metrics")
        self.assertEqual(os.environ.get('RBE_metrics_table'),
                         "rbe_metrics.builds")
        self.assertEqual(
            os.environ.get('RBE_metrics_labels'),
            "source=developer,tool=ninja_reclient,"
            "creds_cache_status=valid,creds_cache_mechanism=GCLOUD")
        self.assertEqual(os.environ.get('RBE_metrics_prefix'),
                         "go.chromium.org")

        mock_metrics_status.assert_called_once_with("out/a")

    @unittest.mock.patch.dict(os.environ,
                              {'AUTONINJA_BUILD_ID': "SOME_RANDOM_ID"},
                              clear=True)
    @unittest.mock.patch('subprocess.call', return_value=0)
    @unittest.mock.patch('ninja.main', return_value=0)
    @unittest.mock.patch('reclient_metrics.check_status', return_value=True)
    def test_ninja_reclient_collect_metrics_cache_expired(
            self, mock_metrics_status, *_):
        reclient_bin_dir = os.path.join('src', 'buildtools', 'reclient')
        reclient_cfg = os.path.join('src', 'buildtools', 'reclient_cfgs',
                                    'reproxy.cfg')
        cache_dir = os.path.join(
            self.root_dir, ".reproxy_cache",
            hashlib.md5(
                os.path.join(self.root_dir, "out", "a",
                             ".reproxy_tmp").encode()).hexdigest())
        write('.gclient', '')
        write('.gclient_entries', 'entries = {"buildtools": "..."}')
        write(os.path.join(reclient_bin_dir, 'version.txt'), '0.0')
        write(reclient_cfg, '0.0')
        write(
            os.path.join(cache_dir, "reproxy.creds"), """
mechanism:  GCLOUD
expiry:  {
  seconds:  %d
}
              """ % (int(time.time())))
        argv = ["ninja_reclient.py", "-C", "out/a", "chrome"]

        self.assertEqual(0, ninja_reclient.main(argv))

        self.assertIn("/SOME_RANDOM_ID", os.environ["RBE_invocation_id"])
        self.assertEqual(os.environ.get('RBE_metrics_project'),
                         "chromium-reclient-metrics")
        self.assertEqual(os.environ.get('RBE_metrics_table'),
                         "rbe_metrics.builds")
        self.assertEqual(
            os.environ.get('RBE_metrics_labels'),
            "source=developer,tool=ninja_reclient,"
            "creds_cache_status=expired,creds_cache_mechanism=GCLOUD")
        self.assertEqual(os.environ.get('RBE_metrics_prefix'),
                         "go.chromium.org")

        mock_metrics_status.assert_called_once_with("out/a")

    @unittest.mock.patch.dict(os.environ, {})
    @unittest.mock.patch('subprocess.call', return_value=0)
    @unittest.mock.patch('ninja.main', return_value=0)
    @unittest.mock.patch('reclient_metrics.check_status', return_value=False)
    def test_ninja_reclient_do_not_collect_metrics(self, mock_metrics_status,
                                                   *_):
        reclient_bin_dir = os.path.join('src', 'buildtools', 'reclient')
        reclient_cfg = os.path.join('src', 'buildtools', 'reclient_cfgs',
                                    'reproxy.cfg')
        write('.gclient', '')
        write('.gclient_entries', 'entries = {"buildtools": "..."}')
        write(os.path.join(reclient_bin_dir, 'version.txt'), '0.0')
        write(reclient_cfg, '0.0')
        argv = ["ninja_reclient.py", "-C", "out/a", "chrome"]

        self.assertEqual(0, ninja_reclient.main(argv))

        self.assertEqual(os.environ.get('RBE_metrics_project'), None)
        self.assertEqual(os.environ.get('RBE_metrics_table'), None)
        self.assertEqual(os.environ.get('RBE_metrics_labels'), None)
        self.assertEqual(os.environ.get('RBE_metrics_prefix'), None)

        mock_metrics_status.assert_called_once_with("out/a")

    @unittest.mock.patch('subprocess.call', return_value=0)
    @unittest.mock.patch('ninja.main', return_value=0)
    @unittest.mock.patch('reclient_metrics.check_status', return_value=True)
    @unittest.mock.patch('reclient_helper.datetime_now')
    def test_ninja_reclient_clears_log_dir(self, mock_now, *_):
        reclient_bin_dir = os.path.join('src', 'buildtools', 'reclient')
        reclient_cfg = os.path.join('src', 'buildtools', 'reclient_cfgs',
                                    'reproxy.cfg')
        write('.gclient', '')
        write('.gclient_entries', 'entries = {"buildtools": "..."}')
        write(os.path.join(reclient_bin_dir, 'version.txt'), '0.0')
        write(reclient_cfg, '0.0')
        argv = ["ninja_reclient.py", "-C", "out/a", "chrome"]

        for i in range(7):
            run_time = datetime.datetime(2017, 3, 16, 20, 0, 40 + i, 0)
            mock_now.return_value = run_time
            with unittest.mock.patch.dict(
                    os.environ,
                {"AUTONINJA_BUILD_ID": "SOME_RANDOM_ID_%d" % i}):
                self.assertEqual(0, ninja_reclient.main(argv))
            run_log_dir = os.path.join(
                self.root_dir, "out", "a", ".reproxy_tmp", "logs",
                "20170316T2000%d.000000_SOME_RANDOM_ID_%d" % (40 + i, i))
            self.assertTrue(os.path.isdir(run_log_dir))
            with open(os.path.join(run_log_dir, "reproxy.rpl"), "w") as f:
                print("Content", file=f)
        log_dir = os.path.join(self.root_dir, "out", "a", ".reproxy_tmp",
                               "logs")
        self.assertTrue(
            os.path.isdir(
                os.path.join(self.root_dir, "out", "a", ".reproxy_tmp",
                             "logs")))
        self.assertTrue(os.path.isdir(log_dir))
        want_remaining_dirs = [
            '20170316T200043.000000_SOME_RANDOM_ID_3',
            '20170316T200046.000000_SOME_RANDOM_ID_6',
            '20170316T200044.000000_SOME_RANDOM_ID_4',
            '20170316T200042.000000_SOME_RANDOM_ID_2',
            '20170316T200045.000000_SOME_RANDOM_ID_5',
        ]

        existing_log_dirs = [
            d for d in os.listdir(log_dir)
            if os.path.isdir(os.path.join(log_dir, d))
        ]
        self.assertCountEqual(existing_log_dirs, want_remaining_dirs)
        for d in want_remaining_dirs:
            self.assertTrue(
                os.path.isfile(
                    os.path.join(self.root_dir, "out", "a", ".reproxy_tmp",
                                 "logs", d, "reproxy.rpl")))

    @unittest.mock.patch('subprocess.call', return_value=0)
    @unittest.mock.patch('ninja.main', side_effect=KeyboardInterrupt())
    def test_ninja_reclient_ninja_interrupted(self, mock_ninja, mock_call):
        reclient_bin_dir = os.path.join('src', 'buildtools', 'reclient')
        reclient_cfg = os.path.join('src', 'buildtools', 'reclient_cfgs',
                                    'reproxy.cfg')
        write('.gclient', '')
        write('.gclient_entries', 'entries = {"buildtools": "..."}')
        write(os.path.join(reclient_bin_dir, 'version.txt'), '0.0')
        write(reclient_cfg, '0.0')
        argv = ["ninja_reclient.py", "-C", "out/a", "chrome"]

        self.assertEqual(1, ninja_reclient.main(argv))

        mock_ninja.assert_called_once_with(argv)
        mock_call.assert_has_calls([
            unittest.mock.call([
                os.path.join(self.root_dir, reclient_bin_dir,
                             'bootstrap' + gclient_paths.GetExeSuffix()),
                "--re_proxy=" +
                os.path.join(self.root_dir, reclient_bin_dir,
                             'reproxy' + gclient_paths.GetExeSuffix()),
                "--cfg=" + os.path.join(self.root_dir, reclient_cfg)
            ]),
            unittest.mock.call([
                os.path.join(self.root_dir, reclient_bin_dir,
                             'bootstrap' + gclient_paths.GetExeSuffix()),
                "--shutdown",
                "--cfg=" + os.path.join(self.root_dir, reclient_cfg)
            ]),
        ])

    @unittest.mock.patch('subprocess.call', return_value=0)
    @unittest.mock.patch('ninja.main', return_value=0)
    def test_ninja_reclient_cfg_not_found(self, mock_ninja, mock_call):
        write('.gclient', '')
        write('.gclient_entries', 'entries = {"buildtools": "..."}')
        write(os.path.join('src', 'buildtools', 'reclient', 'version.txt'),
              '0.0')
        argv = ["ninja_reclient.py", "-C", "out/a", "chrome"]

        self.assertEqual(1, ninja_reclient.main(argv))

        mock_ninja.assert_not_called()
        mock_call.assert_not_called()

    @unittest.mock.patch('subprocess.call', return_value=0)
    @unittest.mock.patch('ninja.main', return_value=0)
    def test_ninja_reclient_bins_not_found(self, mock_ninja, mock_call):
        write('.gclient', '')
        write('.gclient_entries', 'entries = {"buildtools": "..."}')
        write(os.path.join('src', 'buildtools', 'reclient_cfgs', 'reproxy.cfg'),
              '0.0')
        argv = ["ninja_reclient.py", "-C", "out/a", "chrome"]

        self.assertEqual(1, ninja_reclient.main(argv))

        mock_ninja.assert_not_called()
        mock_call.assert_not_called()


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