#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unit tests for platform2.py"""

from __future__ import print_function

import os
import sys

import mock

sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                '..', '..', '..'))
# pylint: disable=wrong-import-position
import platform2
from chromite.lib import cros_test_lib
# pylint: enable=wrong-import-position

PLATFORM_SUBDIR = 'platform'
SYSROOT = '/'
TARGET_PREFIX = '//%s:' % PLATFORM_SUBDIR


class Platform2Configure(cros_test_lib.TestCase):
  """A base class of Platform2 unittest."""

  @staticmethod
  def _CreateTestPlatform2():
    p2 = platform2.Platform2()
    p2.platform_subdir = PLATFORM_SUBDIR
    p2.sysroot = SYSROOT
    return p2

  def _RunWithDesc(self, func, gn_description):
    """Runs Platform2.|func| with fake |gn_description|."""
    p2 = self._CreateTestPlatform2()
    with mock.patch('platform2.Platform2.gn_desc', return_value=gn_description):
      return getattr(p2, func)()


class Platform2ConfigureTest(Platform2Configure):
  """Tests Platform2.configure_test()."""

  @staticmethod
  def _CreateTestData(run_test=True, test_config=None):
    """Generates a template of test data."""

    # It emulates a data that is generated by the templates in
    # //common-mk/BUILDCONFIG.gn for this BUILD.gn rule example
    #
    # group("all") {
    #   deps = ["//platform:test"]
    # }
    #
    # executable("test") {
    #   output_name = "output"
    #
    #   run_test = $run_test
    #   test_config = $test_config
    #
    #   # some required variables
    # }
    if test_config is None:
      test_config = {}
    return {
        TARGET_PREFIX + 'all': {
            'deps': [
                TARGET_PREFIX + 'test',
            ],
        },
        TARGET_PREFIX + 'test': {
            'metadata': {
                '_run_test': [run_test],
                '_test_config': [test_config],
            },
            'outputs': ['output'],
        },
    }

  def _CheckConfigureTest(self, gn_description, expected):
    """Checks configure_test output |expected| outputs with |gn_description|."""
    ret = self._RunWithDesc('configure_test', gn_description)
    self.assertEqual(ret, expected)

  @staticmethod
  def _OutputTemplate(options):
    """Create Output Template.

    Add platform2_test.py and some required options to the beginning.
    """
    platform_tooldir = os.path.dirname(os.path.abspath(__file__))
    p2_test_py = os.path.join(platform_tooldir, 'platform2_test.py')
    prefix = [p2_test_py, '--action=run', '--sysroot=%s' % SYSROOT]
    return prefix + options

  def testMultipleTest(self):
    """Verify it can execute multiple tests."""
    targets = [TARGET_PREFIX + 'test%s' % i for i in range(10)]
    desc_data = {
        TARGET_PREFIX + 'all': {
            'deps': targets,
        },
    }
    for target in targets:
      desc_data[target] = {
          'metadata': {
              '_run_test': [True],
          },
          'outputs': [
              'test-%s' % target,
          ],
      }
    self._CheckConfigureTest(
        desc_data,
        [self._OutputTemplate(['--', 'test-%s' % target])
         for target in targets])

  def testRunTest(self):
    """Verify it executes test only when run_test is true."""
    self._CheckConfigureTest(
        self._CreateTestData(run_test=True),
        [self._OutputTemplate(['--', 'output'])])
    self._CheckConfigureTest(
        self._CreateTestData(run_test=False),
        [])

  def testBooleanConfigs(self):
    """Verify it converts boolean configs to flag options."""
    self._CheckConfigureTest(
        self._CreateTestData(test_config={
            'run_as_root': True,
        }),
        [self._OutputTemplate(['--run_as_root', '--', 'output'])])
    self._CheckConfigureTest(
        self._CreateTestData(test_config={
            'run_as_root': False,
        }),
        [self._OutputTemplate(['--', 'output'])])

  def testStringConfigs(self):
    """Verify it converts string configs to not-flag options."""
    self._CheckConfigureTest(
        self._CreateTestData(test_config={
            'gtest_filter': '-*.RunAsRoot',
        }),
        [self._OutputTemplate(['--gtest_filter=-*.RunAsRoot', '--', 'output'])])


class Platform2ConfigureInstall(Platform2Configure):
  """Tests Platform2.configure_install()."""

  @staticmethod
  def _CreateTestData(sources=None, install_path=None, outputs=None,
                      symlinks=None, recursive=False, options=None,
                      command_type=None):
    """Generates a template of test data."""

    # It emulates a data that is generated by the templates in
    # //common-mk/BUILDCONFIG.gn for this BUILD.gn rule example
    #
    # group("all") {
    #   deps = ["//platform:install"]
    # }
    #
    # install_config("install") {
    #   sources = $sources
    #   install_path = $install_path
    #   outputs = $outputs
    #   symlinks = $symlinks
    #   recursive = $recursive
    #   options = $options
    #   type = $target_type
    #
    #   # some required variables
    # }
    install_config = {
        'sources': sources,
        'install_path': install_path,
        'outputs': outputs,
        'symlinks': symlinks,
        'recursive': recursive,
        'options': options,
        'type': command_type,
    }
    metadata = {
        '_install_config': [install_config]
    }
    return {
        TARGET_PREFIX + 'all': {
            'deps': [
                TARGET_PREFIX + 'install',
            ],
        },
        TARGET_PREFIX + 'install': {
            'metadata': metadata,
        },
    }

  @mock.patch('ebuild_function.generate', return_value=[['test', 'command']])
  def testEbuildParameter(self, generate_mock):
    """Makes sure the parameter passed to ebuild_function correctly."""
    gn_desc = self._CreateTestData(sources=['source'], install_path='/path',
                                   outputs=['output'], symlinks=['symlink'],
                                   recursive=True, options='-m0644',
                                   command_type='executable')
    self._RunWithDesc('configure_install', gn_desc)
    generate_mock.assert_called_with(sources=['source'], install_path='/path',
                                     outputs=['output'], symlinks=['symlink'],
                                     recursive=True, options='-m0644',
                                     command_type='executable')

  @mock.patch('ebuild_function.generate', return_value=[['test', 'command']])
  def testEbuildParameterWithoutNewNames(self, generate_mock):
    """Makes sure the parameter passed to ebuild_function correctly."""
    gn_desc = self._CreateTestData(sources=['source'], install_path='/path',
                                   recursive=True, options='-m0644',
                                   command_type='executable')
    self._RunWithDesc('configure_install', gn_desc)
    generate_mock.assert_called_with(sources=['source'], install_path='/path',
                                     outputs=None, symlinks=None,
                                     recursive=True, options='-m0644',
                                     command_type='executable')

  @mock.patch('ebuild_function.generate', return_value=[['test', 'command']])
  def testWithoutSources(self, generate_mock):
    """Makes sure it returns empty list when sources aren't specified."""
    self._RunWithDesc('configure_install', self._CreateTestData())
    self.assertEqual(generate_mock.call_count, 0)

  @mock.patch('ebuild_function.generate', return_value=[['test', 'command']])
  def testWithSources(self, generate_mock):
    """Makes sure it returns an install command when sources are specified."""
    gn_desc = self._CreateTestData(sources=['source'])
    self._RunWithDesc('configure_install', gn_desc)
    self.assertEqual(generate_mock.call_count, 1)

  @mock.patch('ebuild_function.generate', return_value=[['test', 'command']])
  def testMultipleDifferentPathCommands(self, generate_mock):
    """Checks outputs are separated when having the different install_paths."""
    num_install = 10
    targets = [TARGET_PREFIX + 'test%s' % str(i) for i in range(num_install)]
    gn_desc = {
        TARGET_PREFIX + 'all': {
            'deps': targets,
        },
    }
    for target in targets:
      gn_desc[target] = {
          'metadata': {
              '_install_config': [{
                  'install_path': target,
                  'sources': ['source'],
              }],
          },
      }
    self._RunWithDesc('configure_install', gn_desc)
    self.assertEqual(generate_mock.call_count, 10)

  @mock.patch('ebuild_function.generate', return_value=[['test', 'command']])
  def testMultipleSamePathCommands(self, generate_mock):
    """Checks an output is combined when having the same install_paths."""
    num_install = 10
    targets = [TARGET_PREFIX + 'test%s' % str(i) for i in range(num_install)]
    gn_desc = {
        TARGET_PREFIX + 'all': {
            'deps': targets,
        },
    }
    for target in targets:
      gn_desc[target] = {
          'metadata': {
              '_install_config': [{
                  'install_path': '/path',
                  'sources': ['source'],
              }],
          },
      }
    self._RunWithDesc('configure_install', gn_desc)
    self.assertEqual(generate_mock.call_count, 1)

  @mock.patch('ebuild_function.generate', return_value=[['test', 'command']])
  def testMixedCommands(self, generate_mock):
    """Checks it returns two commands when having both new-cmd and do-cmd."""

    # group("all") {
    #   deps = [
    #     "//platform:doins",
    #     "//platform:newins",
    #   ]
    # }
    #
    # install_config("doins") {
    #   sources = "source-doins"
    #   install_path = "/path"
    # }
    # install_config("newins") {
    #   sources = "source-oldins"
    #   install_path = "/path"
    #   outputs = "source-newins"
    # }

    doins_target = TARGET_PREFIX + 'doins1'
    newins_target = TARGET_PREFIX + 'newins'
    gn_desc = {
        TARGET_PREFIX + 'all': {
            'deps': [
                doins_target,
                newins_target,
            ],
        }, doins_target: {
            'metadata': {
                '_install_config': [{
                    'install_path': '/path',
                    'sources': ['source-doins'],
                }],
            }
        }, newins_target: {
            'metadata': {
                '_install_config': [{
                    'install_path': '/path',
                    'sources': ['source-oldins'],
                    'outputs': ['source-newins'],
                }],
            },
        }
    }
    self._RunWithDesc('configure_install', gn_desc)
    generate_mock.assert_any_call(sources=['source-doins'],
                                  install_path='/path',
                                  outputs=None, symlinks=None,
                                  recursive=None, options=None,
                                  command_type=None)
    generate_mock.assert_any_call(sources=['source-oldins'],
                                  install_path='/path',
                                  outputs=['source-newins'], symlinks=None,
                                  recursive=None, options=None,
                                  command_type=None)


if __name__ == '__main__':
  cros_test_lib.main(module=__name__)
