# pylint: disable=g-backslash-continuation
# Copyright 2023 The Bazel 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.
# pylint: disable=g-long-ternary

import os
import tempfile
import unittest

from src.test.py.bazel import test_base
from src.test.py.bazel.bzlmod.test_utils import BazelRegistry
from src.test.py.bazel.bzlmod.test_utils import scratchFile


class BazelRepoMappingTest(test_base.TestBase):

  def setUp(self):
    test_base.TestBase.setUp(self)
    self.registries_work_dir = tempfile.mkdtemp(dir=self._test_cwd)
    self.main_registry = BazelRegistry(
        os.path.join(self.registries_work_dir, 'main')
    )
    self.main_registry.createCcModule('aaa', '1.0').createCcModule(
        'aaa', '1.1'
    ).createCcModule('bbb', '1.0', {'aaa': '1.0'}).createCcModule(
        'bbb', '1.1', {'aaa': '1.1'}
    ).createCcModule(
        'ccc', '1.1', {'aaa': '1.1', 'bbb': '1.1'}
    )
    self.ScratchFile(
        '.bazelrc',
        [
            # In ipv6 only network, this has to be enabled.
            # 'startup --host_jvm_args=-Djava.net.preferIPv6Addresses=true',
            'build --enable_bzlmod',
            'build --registry=' + self.main_registry.getURL(),
            # We need to have BCR here to make sure built-in modules like
            # bazel_tools can work.
            'build --registry=https://bcr.bazel.build',
            'build --verbose_failures',
            # Set an explicit Java language version
            'build --java_language_version=8',
            'build --tool_java_language_version=8',
            'build --lockfile_mode=update',
        ],
    )
    self.ScratchFile('WORKSPACE')
    # The existence of WORKSPACE.bzlmod prevents WORKSPACE prefixes or suffixes
    # from being used; this allows us to test built-in modules actually work
    self.ScratchFile('WORKSPACE.bzlmod')

  def testRunfilesRepoMappingManifest(self):
    self.main_registry.setModuleBasePath('projects')
    projects_dir = self.main_registry.projects

    # Set up a "bare_rule" module that contains the "bare_test" rule which
    # passes runfiles along
    self.main_registry.createLocalPathModule('bare_rule', '1.0', 'bare_rule')
    projects_dir.joinpath('bare_rule').mkdir(exist_ok=True)
    scratchFile(projects_dir.joinpath('bare_rule', 'WORKSPACE'))
    scratchFile(projects_dir.joinpath('bare_rule', 'BUILD'))
    # The working directory of a test is the subdirectory of the runfiles
    # directory corresponding to the main repository.
    scratchFile(
        projects_dir.joinpath('bare_rule', 'defs.bzl'),
        [
            'def _bare_test_impl(ctx):',
            '  exe = ctx.actions.declare_file(ctx.label.name)',
            '  ctx.actions.write(exe,',
            (
                '    "#/bin/bash\\nif [[ ! -f ../_repo_mapping || ! -s'
                ' ../_repo_mapping ]]; then\\necho >&2 \\"ERROR: cannot find'
                ' repo mapping manifest file\\"\\nexit 1\\nfi",'
            ),
            '    True)',
            '  runfiles = ctx.runfiles(files=ctx.files.data)',
            '  for data in ctx.attr.data:',
            '    runfiles = runfiles.merge(data[DefaultInfo].default_runfiles)',
            (
                '  return DefaultInfo(files=depset(direct=[exe]),'
                ' executable=exe, runfiles=runfiles)'
            ),
            'bare_test=rule(',
            '  implementation=_bare_test_impl,',
            '  attrs={"data":attr.label_list(allow_files=True)},',
            '  test=True,',
            ')',
        ],
    )

    # Now set up a project tree shaped like a diamond
    self.ScratchFile(
        'MODULE.bazel',
        [
            'module(name="me",version="1.0")',
            'bazel_dep(name="foo",version="1.0")',
            'bazel_dep(name="bar",version="2.0")',
            'bazel_dep(name="bare_rule",version="1.0")',
        ],
    )
    self.ScratchFile('WORKSPACE')
    self.ScratchFile('WORKSPACE.bzlmod', ['workspace(name="me_ws")'])
    self.ScratchFile(
        'BUILD',
        [
            'load("@bare_rule//:defs.bzl", "bare_test")',
            'bare_test(name="me",data=["@foo"])',
        ],
    )
    self.main_registry.createLocalPathModule(
        'foo', '1.0', 'foo', {'quux': '1.0', 'bare_rule': '1.0'}
    )
    self.main_registry.createLocalPathModule(
        'bar', '2.0', 'bar', {'quux': '2.0', 'bare_rule': '1.0'}
    )
    self.main_registry.createLocalPathModule(
        'quux', '1.0', 'quux1', {'bare_rule': '1.0'}
    )
    self.main_registry.createLocalPathModule(
        'quux', '2.0', 'quux2', {'bare_rule': '1.0'}
    )
    for dir_name, build_file in [
        ('foo', 'bare_test(name="foo",data=["@quux"])'),
        ('bar', 'bare_test(name="bar",data=["@quux"])'),
        ('quux1', 'bare_test(name="quux")'),
        ('quux2', 'bare_test(name="quux")'),
    ]:
      projects_dir.joinpath(dir_name).mkdir(exist_ok=True)
      scratchFile(projects_dir.joinpath(dir_name, 'WORKSPACE'))
      scratchFile(
          projects_dir.joinpath(dir_name, 'BUILD'),
          [
              'load("@bare_rule//:defs.bzl", "bare_test")',
              'package(default_visibility=["//visibility:public"])',
              build_file,
          ],
      )

    # We use a shell script to check that the binary itself can see the repo
    # mapping manifest. This obviously doesn't work on Windows, so we just build
    # the target. TODO(wyv): make this work on Windows by using Batch.
    # On Linux and macOS, the script is executed in the sandbox, so we verify
    # that the repository mapping is present in it.
    bazel_command = 'build' if self.IsWindows() else 'test'

    # Finally we get to build stuff!
    exit_code, stderr, stdout = self.RunBazel(
        [bazel_command, '//:me', '--test_output=errors'], allow_failure=True
    )
    self.AssertExitCode(0, exit_code, stderr, stdout)

    paths = ['bazel-bin/me.repo_mapping']
    if not self.IsWindows():
      paths.append('bazel-bin/me.runfiles/_repo_mapping')
    for path in paths:
      with open(self.Path(path), 'r') as f:
        self.assertEqual(
            f.read().strip(),
            """,foo,foo~1.0
,me,_main
,me_ws,_main
foo~1.0,foo,foo~1.0
foo~1.0,quux,quux~2.0
quux~2.0,quux,quux~2.0""",
        )
    with open(self.Path('bazel-bin/me.runfiles_manifest')) as f:
      self.assertIn('_repo_mapping ', f.read())

    exit_code, stderr, stdout = self.RunBazel(
        [bazel_command, '@bar//:bar', '--test_output=errors'],
        allow_failure=True,
    )
    self.AssertExitCode(0, exit_code, stderr, stdout)

    paths = ['bazel-bin/external/bar~2.0/bar.repo_mapping']
    if not self.IsWindows():
      paths.append('bazel-bin/external/bar~2.0/bar.runfiles/_repo_mapping')
    for path in paths:
      with open(self.Path(path), 'r') as f:
        self.assertEqual(
            f.read().strip(),
            """bar~2.0,bar,bar~2.0
bar~2.0,quux,quux~2.0
quux~2.0,quux,quux~2.0""",
        )
    with open(
        self.Path('bazel-bin/external/bar~2.0/bar.runfiles_manifest')
    ) as f:
      self.assertIn('_repo_mapping ', f.read())

  def testBashRunfilesLibraryRepoMapping(self):
    self.main_registry.setModuleBasePath('projects')
    projects_dir = self.main_registry.projects

    self.main_registry.createLocalPathModule('data', '1.0', 'data')
    projects_dir.joinpath('data').mkdir(exist_ok=True)
    scratchFile(projects_dir.joinpath('data', 'WORKSPACE'))
    scratchFile(projects_dir.joinpath('data', 'foo.txt'), ['hello'])
    scratchFile(
        projects_dir.joinpath('data', 'BUILD'), ['exports_files(["foo.txt"])']
    )

    self.main_registry.createLocalPathModule(
        'test', '1.0', 'test', {'data': '1.0'}
    )
    projects_dir.joinpath('test').mkdir(exist_ok=True)
    scratchFile(projects_dir.joinpath('test', 'WORKSPACE'))
    scratchFile(
        projects_dir.joinpath('test', 'BUILD'),
        [
            'sh_test(',
            '    name = "test",',
            '    srcs = ["test.sh"],',
            '    data = ["@data//:foo.txt"],',
            '    args = ["$(rlocationpath @data//:foo.txt)"],',
            '    deps = ["@bazel_tools//tools/bash/runfiles"],',
            ')',
        ],
    )
    test_script = projects_dir.joinpath('test', 'test.sh')
    scratchFile(
        test_script,
        """#!/usr/bin/env bash
# --- begin runfiles.bash initialization v2 ---
# Copy-pasted from the Bazel Bash runfiles library v2.
set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
  source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
  source "$0.runfiles/$f" 2>/dev/null || \
  source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
  source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
  { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v2 ---
[[ -f  "$(rlocation $1)" ]] || exit 1
[[ -f  "$(rlocation data/foo.txt)" ]] || exit 2
""".splitlines(),
    )
    os.chmod(test_script, 0o755)

    self.ScratchFile('MODULE.bazel', ['bazel_dep(name="test",version="1.0")'])
    self.ScratchFile('WORKSPACE')

    # Run sandboxed on Linux and macOS.
    exit_code, stderr, stdout = self.RunBazel(
        [
            'test',
            '@test//:test',
            '--test_output=errors',
            '--test_env=RUNFILES_LIB_DEBUG=1',
        ],
        allow_failure=True,
    )
    self.AssertExitCode(exit_code, 0, stderr, stdout)
    # Run unsandboxed on all platforms.
    exit_code, stderr, stdout = self.RunBazel(
        ['run', '@test//:test'],
        allow_failure=True,
        env_add={'RUNFILES_LIB_DEBUG': '1'},
    )
    self.AssertExitCode(exit_code, 0, stderr, stdout)

  def testCppRunfilesLibraryRepoMapping(self):
    self.main_registry.setModuleBasePath('projects')
    projects_dir = self.main_registry.projects

    self.main_registry.createLocalPathModule('data', '1.0', 'data')
    projects_dir.joinpath('data').mkdir(exist_ok=True)
    scratchFile(projects_dir.joinpath('data', 'WORKSPACE'))
    scratchFile(projects_dir.joinpath('data', 'foo.txt'), ['hello'])
    scratchFile(
        projects_dir.joinpath('data', 'BUILD'), ['exports_files(["foo.txt"])']
    )

    self.main_registry.createLocalPathModule(
        'test', '1.0', 'test', {'data': '1.0'}
    )
    projects_dir.joinpath('test').mkdir(exist_ok=True)
    scratchFile(projects_dir.joinpath('test', 'WORKSPACE'))
    scratchFile(
        projects_dir.joinpath('test', 'BUILD'),
        [
            'cc_test(',
            '    name = "test",',
            '    srcs = ["test.cpp"],',
            '    data = ["@data//:foo.txt"],',
            '    args = ["$(rlocationpath @data//:foo.txt)"],',
            '    deps = ["@bazel_tools//tools/cpp/runfiles"],',
            ')',
        ],
    )
    scratchFile(
        projects_dir.joinpath('test', 'test.cpp'),
        [
            '#include <cstdlib>',
            '#include <fstream>',
            '#include "tools/cpp/runfiles/runfiles.h"',
            'using bazel::tools::cpp::runfiles::Runfiles;',
            'int main(int argc, char** argv) {',
            (
                '  Runfiles* runfiles = Runfiles::Create(argv[0],'
                ' BAZEL_CURRENT_REPOSITORY);'
            ),
            '  std::ifstream f1(runfiles->Rlocation(argv[1]));',
            '  if (!f1.good()) std::exit(1);',
            '  std::ifstream f2(runfiles->Rlocation("data/foo.txt"));',
            '  if (!f2.good()) std::exit(2);',
            '}',
        ],
    )

    self.ScratchFile('MODULE.bazel', ['bazel_dep(name="test",version="1.0")'])
    self.ScratchFile('WORKSPACE')

    # Run sandboxed on Linux and macOS.
    exit_code, stderr, stdout = self.RunBazel(
        ['test', '@test//:test', '--test_output=errors'], allow_failure=True
    )
    self.AssertExitCode(exit_code, 0, stderr, stdout)
    # Run unsandboxed on all platforms.
    exit_code, stderr, stdout = self.RunBazel(
        ['run', '@test//:test'], allow_failure=True
    )
    self.AssertExitCode(exit_code, 0, stderr, stdout)

  def testJavaRunfilesLibraryRepoMapping(self):
    self.main_registry.setModuleBasePath('projects')
    projects_dir = self.main_registry.projects

    self.main_registry.createLocalPathModule('data', '1.0', 'data')
    projects_dir.joinpath('data').mkdir(exist_ok=True)
    scratchFile(projects_dir.joinpath('data', 'WORKSPACE'))
    scratchFile(projects_dir.joinpath('data', 'foo.txt'), ['hello'])
    scratchFile(
        projects_dir.joinpath('data', 'BUILD'), ['exports_files(["foo.txt"])']
    )

    self.main_registry.createLocalPathModule(
        'test', '1.0', 'test', {'data': '1.0'}
    )
    projects_dir.joinpath('test').mkdir(exist_ok=True)
    scratchFile(projects_dir.joinpath('test', 'WORKSPACE'))
    scratchFile(
        projects_dir.joinpath('test', 'BUILD'),
        [
            'java_test(',
            '    name = "test",',
            '    srcs = ["Test.java"],',
            '    main_class = "com.example.Test",',
            '    use_testrunner = False,',
            '    data = ["@data//:foo.txt"],',
            '    args = ["$(rlocationpath @data//:foo.txt)"],',
            '    deps = ["@bazel_tools//tools/java/runfiles"],',
            ')',
        ],
    )
    scratchFile(
        projects_dir.joinpath('test', 'Test.java'),
        [
            'package com.example;',
            '',
            'import com.google.devtools.build.runfiles.AutoBazelRepository;',
            'import com.google.devtools.build.runfiles.Runfiles;',
            '',
            'import java.io.File;',
            'import java.io.IOException;',
            '',
            '@AutoBazelRepository',
            'public class Test {',
            '  public static void main(String[] args) throws IOException {',
            '    Runfiles.Preloaded rp = Runfiles.preload();',
            '    if (!new File(rp.unmapped().rlocation(args[0])).exists()) {',
            '      System.exit(1);',
            '    }',
            (
                '    if (!new'
                ' File(rp.withSourceRepository(AutoBazelRepository_Test.NAME).rlocation("data/foo.txt")).exists()) {'
            ),
            '      System.exit(1);',
            '    }',
            '  }',
            '}',
        ],
    )

    self.ScratchFile('MODULE.bazel', ['bazel_dep(name="test",version="1.0")'])
    self.ScratchFile('WORKSPACE')

    # Run sandboxed on Linux and macOS.
    exit_code, stderr, stdout = self.RunBazel(
        [
            'test',
            '@test//:test',
            '--test_output=errors',
            '--test_env=RUNFILES_LIB_DEBUG=1',
        ],
        allow_failure=True,
    )
    self.AssertExitCode(exit_code, 0, stderr, stdout)
    # Run unsandboxed on all platforms.
    exit_code, stderr, stdout = self.RunBazel(
        ['run', '@test//:test'],
        allow_failure=True,
        env_add={'RUNFILES_LIB_DEBUG': '1'},
    )
    self.AssertExitCode(exit_code, 0, stderr, stdout)


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