# Copyright 2020 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.
import os
import unittest
from scripts.ctexplain.bazel_api import BazelApi
from scripts.ctexplain.ctexplain_types import NullConfiguration
from src.test.py.bazel import test_base


class BazelApiTest(test_base.TestBase):

  _bazel_api: BazelApi = None

  def setUp(self):
    test_base.TestBase.setUp(self)
    self._bazel_api = BazelApi(
        lambda *args, **kwargs: self.RunBazel(
            allow_failure=True, *args, **kwargs
        )
    )

  def tearDown(self):
    test_base.TestBase.tearDown(self)

  def testBasicCquery(self):
    self.ScratchFile(
        'testapp/BUILD',
        [
            'filegroup(name = "fg", srcs = ["a.file"])',
        ],
    )
    res = self._bazel_api.cquery(['//testapp:all'])
    success = res[0]
    cts = res[2]
    self.assertTrue(success)
    self.assertEqual(len(cts), 1)
    self.assertEqual(cts[0].label, '//testapp:fg')
    self.assertIsNone(cts[0].config)
    self.assertGreater(len(cts[0].config_hash), 6)
    self.assertIn('PlatformConfiguration', cts[0].transitive_fragments)

  def testFailedCquery(self):
    self.ScratchFile(
        'testapp/BUILD',
        [
            'filegroup(name = "fg", srcs = ["a.file"])',
        ],
    )
    success, stderr, cts = self._bazel_api.cquery(['//testapp:typo'])
    self.assertFalse(success)
    self.assertEqual(len(cts), 0)
    self.assertIn(
        "target 'typo' not declared in package 'testapp'",
        os.linesep.join(stderr),
    )

  def testTransitiveFragmentsAccuracy(self):
    self.ScratchFile(
        'MODULE.bazel', ["bazel_dep(name = 'rules_cc', version = '0.2.14')"]
    )
    self.ScratchFile(
        'testapp/BUILD',
        [
            'load("@rules_cc//cc:cc_binary.bzl", "cc_binary")',
            'filegroup(name = "fg", srcs = ["a.file"])',
            'filegroup(name = "ccfg", srcs = [":ccbin"])',
            'cc_binary(name = "ccbin", srcs = ["ccbin.cc"])',
        ],
    )
    cts1 = self._bazel_api.cquery(['//testapp:fg'])[2]
    self.assertNotIn('CppConfiguration', cts1[0].transitive_fragments)
    cts2 = self._bazel_api.cquery(['//testapp:ccfg'])[2]
    self.assertIn('CppConfiguration', cts2[0].transitive_fragments)

  def testGetTargetConfig(self):
    self.ScratchFile(
        'testapp/BUILD',
        [
            'filegroup(name = "fg", srcs = ["a.file"])',
        ],
    )
    cts = self._bazel_api.cquery(['//testapp:fg'])[2]
    config = self._bazel_api.get_config(cts[0].config_hash)
    expected_fragments = ['PlatformConfiguration', 'JavaConfiguration']
    for exp in expected_fragments:
      self.assertIn(exp, config.fragments.keys())
    core_options = config.options['CoreOptions']
    self.assertIsNotNone(core_options)
    self.assertIn(('stamp', 'false'), core_options.items())

  def testGetNullConfig(self):
    self.ScratchFile(
        'testapp/BUILD',
        [
            'filegroup(name = "fg", srcs = ["a.file"])',
        ],
    )
    cts = self._bazel_api.cquery(['//testapp:a.file'])[2]
    config = self._bazel_api.get_config(cts[0].config_hash)
    self.assertIsInstance(config, NullConfiguration)
    # Null configurations have no information by definition.
    self.assertEqual(len(config.fragments), 0)
    self.assertEqual(len(config.options), 0)

  def testConfigFragmentsMap(self):
    self.ScratchFile(
        'testapp/BUILD',
        [
            'filegroup(name = "fg", srcs = ["a.file"])',
        ],
    )
    cts = self._bazel_api.cquery(['//testapp:fg'])[2]
    fragments_map = self._bazel_api.get_config(cts[0].config_hash).fragments
    self.assertIn('PlatformOptions', fragments_map['PlatformConfiguration'])
    self.assertIn(
        'ShellConfiguration$Options', fragments_map['ShellConfiguration']
    )

  def testConfigWithDefines(self):
    self.ScratchFile(
        'testapp/BUILD',
        [
            'filegroup(name = "fg", srcs = ["a.file"])',
        ],
    )
    cquery_args = ['//testapp:fg', '--define', 'a=b']
    cts = self._bazel_api.cquery(cquery_args)[2]
    config = self._bazel_api.get_config(cts[0].config_hash)
    user_defined_options = config.options['user-defined']
    self.assertIsNotNone(user_defined_options)
    self.assertDictEqual(dict(user_defined_options), {'--define:a': 'b'})

  def testConfigWithStarlarkFlags(self):
    self.ScratchFile(
        'testapp/defs.bzl',
        [
            'def _flag_impl(settings, attr):',
            '  pass',
            'string_flag = rule(',
            '  implementation = _flag_impl,',
            '  build_setting = config.string(flag = True)',
            ')',
        ],
    )
    self.ScratchFile(
        'testapp/BUILD',
        [
            'load(":defs.bzl", "string_flag")',
            'string_flag(name = "my_flag", build_setting_default = "nada")',
            'filegroup(name = "fg", srcs = ["a.file"])',
        ],
    )
    cquery_args = ['//testapp:fg', '--//testapp:my_flag=algo']
    cts = self._bazel_api.cquery(cquery_args)[2]
    config = self._bazel_api.get_config(cts[0].config_hash)
    user_defined_options = config.options['user-defined']
    self.assertIsNotNone(user_defined_options)
    self.assertDictEqual(
        dict(user_defined_options), {'//testapp:my_flag': 'algo'}
    )


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