# Copyright 2020 Google LLC
#
# 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
#
#     https://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.
"""Test config."""

import tempfile
import unittest
from . import config

_TEST_CONFIG_XML = """<config>
  <target name="android_target_1">
    <build_config>
      <goal name="droid"/>
      <goal name="dist"/>
    </build_config>
  </target>
  <target name="android_target_2" tags="cool,hot">
    <config name="fmc_framework_images" value="image1,image2"/>
    <config name="fmc_misc_info_keys" value="misc_info_keys.txt"/>
    <goal name="common_goal"/>
    <build_config tags="warm">
      <goal name="droid"/>
      <goal name="dist"/>
      <goal name="goal_for_android_target_2"/>
    </build_config>
    <build_config name="build_target_2" tags="dry">
      <config name="fmc_framework_images" value="bt1,bt2"/>
      <config name="fmc_misc_info_keys" value="misc_info_keys_2.txt"/>
      <goal name="droid"/>
      <goal name="VAR=a"/>
    </build_config>
  </target>
  <target name="android_target_3" tags="">
    <build_config>
      <goal name="droid"/>
    </build_config>
  </target>
  <target name="some_target" android_target="android_target_4">
    <goal name="droid"/>
    <build_config>
    </build_config>
  </target>
  <target name="no_goals_target">
    <build_config/>
  </target>
</config>
"""

_TEST_CONTEXTS_CONFIG_XML = """<config>
  <target name="test_target">
    <build_config>

      <!-- no contexts attribute: always selected -->
      <goal name="droid"/>

      <!-- empty contexts attribute: always selected -->
      <goal name="always" contexts=""/>

      <!-- selected if ci context requested -->
      <goal name="dist" contexts="ci"/>

      <!-- selected if x context requested -->
      <goal name="VAR=value" contexts="x"/>

      <!-- selected if ci or x context requested -->
      <goal name="extra_goal" contexts="ci,x"/>

    </build_config>
  </target>
</config>
"""

class ConfigTest(unittest.TestCase):
  """unittest for Config."""

  def testConfigFilenameNone(self):
    cfg = config.factory(None)
    self.assertIsNone(cfg)

  def testAvailableBuildTargets(self):
    with tempfile.NamedTemporaryFile('w+t') as test_config:
      test_config.write(_TEST_CONFIG_XML)
      test_config.flush()
      cfg = config.factory(test_config.name)
      self.assertListEqual(
          cfg.get_available_build_targets(),
          # Sorted; not in document order.
          [
              'android_target_1',
              'android_target_2',
              'android_target_3',
              'build_target_2',
              'no_goals_target',
              'some_target',
          ])

  def testBuildTargetTags(self):
    with tempfile.NamedTemporaryFile('w+t') as test_config:
      test_config.write(_TEST_CONFIG_XML)
      test_config.flush()
      cfg = config.factory(test_config.name)

      self.assertSetEqual(cfg.get_tags('android_target_1'), set())
      self.assertSetEqual(
          cfg.get_tags('android_target_2'), set(['cool', 'hot', 'warm']))
      self.assertSetEqual(
          cfg.get_tags('build_target_2'), set(['cool', 'hot', 'dry']))
      self.assertSetEqual(cfg.get_tags('android_target_3'), set())

      self.assertFalse(cfg.has_tag('android_target_1', 'cool'))
      self.assertFalse(cfg.has_tag('android_target_1', 'hot'))
      self.assertFalse(cfg.has_tag('android_target_1', 'meh'))

      self.assertTrue(cfg.has_tag('android_target_2', 'cool'))
      self.assertTrue(cfg.has_tag('android_target_2', 'hot'))
      self.assertFalse(cfg.has_tag('android_target_2', 'meh'))

      self.assertTrue(cfg.has_tag('build_target_2', 'cool'))
      self.assertTrue(cfg.has_tag('build_target_2', 'hot'))
      self.assertFalse(cfg.has_tag('build_target_2', 'meh'))

      self.assertFalse(cfg.has_tag('android_target_3', 'cool'))
      self.assertFalse(cfg.has_tag('android_target_3', 'hot'))
      self.assertFalse(cfg.has_tag('android_target_3', 'meh'))

  def testBuildTargetToAndroidTarget(self):
    with tempfile.NamedTemporaryFile('w+t') as test_config:
      test_config.write(_TEST_CONFIG_XML)
      test_config.flush()
      cfg = config.factory(test_config.name)

      # Test that build_target android_target_1 -> android_target_1.
      self.assertEqual(
          cfg.get_build_config_android_target('android_target_1'),
          'android_target_1')

      # Test that build_target android_target_2 -> android_target_2.
      self.assertEqual(
          cfg.get_build_config_android_target('android_target_2'),
          'android_target_2')

      # Test that build_target build_target_2 -> android_target_2.
      self.assertEqual(
          cfg.get_build_config_android_target('build_target_2'),
          'android_target_2')

      # Test overriding android_target property
      self.assertEqual(
          cfg.get_build_config_android_target('some_target'),
          'android_target_4')

  def testBuildTargetToBuildGoals(self):
    with tempfile.NamedTemporaryFile('w+t') as test_config:
      test_config.write(_TEST_CONFIG_XML)
      test_config.flush()
      cfg = config.factory(test_config.name)

      # Test that build_target android_target_1 has goals droid and dist.
      self.assertEqual(
          cfg.get_build_goals('android_target_1'),
          ['droid', 'dist'])

      # Test that build_target android_target_2 has goals droid, dist, and
      # goal_for_android_target_2.
      self.assertEqual(
          cfg.get_build_goals('android_target_2'),
          ['common_goal', 'droid', 'dist', 'goal_for_android_target_2'])

      # Test that build_target build_target_2 has goals droid and VAR=a.
      self.assertEqual(
          cfg.get_build_goals('build_target_2'),
          ['common_goal', 'droid', 'VAR=a'])

      # Test empty goals
      self.assertEqual(cfg.get_build_goals('no_goals_target'),[])

  def testBuildTargetToBuildGoalsWithContexts(self):
    with tempfile.NamedTemporaryFile('w+t') as test_config:
      test_config.write(_TEST_CONTEXTS_CONFIG_XML)
      test_config.flush()
      cfg = config.factory(test_config.name)

      # Test that when contexts is the default (empty), we select only the
      # "always" goals.

      build_goals = cfg.get_build_goals('test_target')
      self.assertEqual(build_goals, ['droid', 'always'])

      # Test that when contexts is explicitly empty, we select only the
      # "always" goals.

      build_goals = cfg.get_build_goals('test_target', set())
      self.assertEqual(build_goals, ['droid', 'always'])

      # Similarly, test that when contexts is doesn't match any goal_contexts,
      # we select only the "always" goals.

      build_goals = cfg.get_build_goals('test_target', set('no_matchy'))
      self.assertEqual(build_goals, ['droid', 'always'])

      # Test that when contexts is set(['x']), we select the "always" goals and
      # the x goals.

      build_goals = cfg.get_build_goals('test_target', set(['x']))

      self.assertEqual(
          build_goals,
          ['droid', 'always', 'VAR=value', 'extra_goal'])

      # Test that when requested_contexts is set(['ci', 'x']), we select the
      # "always" goals, the ci goals, and the x goals.

      build_goals = cfg.get_build_goals('test_target', set(['ci', 'x']))

      self.assertEqual(
          build_goals,
          ['droid', 'always', 'dist', 'VAR=value', 'extra_goal'])

  def testAllowReadWriteAll(self):
    with tempfile.NamedTemporaryFile('w+t') as test_config:
      test_config.write("""<?xml version="1.0" encoding="UTF-8" ?>
        <config>
          <target name="target_allowed" allow_readwrite_all="true">
            <build_config>
              <goal name="droid"/>
            </build_config>
            <allow_readwrite_all/>
          </target>
          <target name="target_not_allowed">
            <build_config>
              <goal name="droid"/>
            </build_config>
          </target>
          <target name="target_also_not_allowed" allow_readwrite_all="false">
            <build_config>
              <goal name="droid"/>
            </build_config>
          </target>
        </config>""")
      test_config.flush()
      cfg = config.factory(test_config.name)

      self.assertTrue(cfg.get_allow_readwrite_all('target_allowed'))

      self.assertFalse(cfg.get_allow_readwrite_all('target_not_allowed'))

      self.assertFalse(cfg.get_allow_readwrite_all('target_also_not_allowed'))

  def testAllowedProjectsFile(self):
    with tempfile.NamedTemporaryFile('w+t') as test_config:
      test_config.write(
          '<?xml version="1.0" encoding="UTF-8" ?>'
          '<config>'
          '  <target name="target_name">'
          '    <build_config allowed_projects_file="path/to/default/build/config/allowed_projects.xml">'
          '      <goal name="build_goal"/>'
          '    </build_config>'
          '    <build_config name="has_allowed_projects_file" allowed_projects_file="path/to/named/build/config/allowed_projects.xml">'
          '      <goal name="build_goal"/>'
          '    </build_config>'
          '    <build_config name="no_allowed_projects_file">'
          '      <goal name="build_goal"/>'
          '    </build_config>'
          '  </target>'
          '</config>')
      test_config.flush()
      cfg = config.factory(test_config.name)

      self.assertEqual(
          cfg.get_allowed_projects_file('target_name'),
          'path/to/default/build/config/allowed_projects.xml')
      self.assertEqual(
          cfg.get_allowed_projects_file('has_allowed_projects_file'),
          'path/to/named/build/config/allowed_projects.xml')
      self.assertIsNone(
          cfg.get_allowed_projects_file('no_allowed_projects_file'))

  def testMergeConfig(self):
    with tempfile.NamedTemporaryFile('w+t') as test_config:
      test_config.write(_TEST_CONFIG_XML)
      test_config.flush()
      cfg = config.factory(test_config.name)

      bc_at2 = cfg.get_build_config('android_target_2')
      self.assertDictEqual(bc_at2.configurations, {
        'fmc_framework_images': 'image1,image2',
        'fmc_misc_info_keys': 'misc_info_keys.txt'
      })

      bc_bt2 = cfg.get_build_config('build_target_2')
      self.assertDictEqual(bc_bt2.configurations, {
        'fmc_framework_images': 'bt1,bt2',
        'fmc_misc_info_keys': 'misc_info_keys_2.txt'
      })

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