# Copyright 2016 The Cobalt 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.
"""Starboard Creator Ci20 platform configuration."""

import logging
import os
import sys

from starboard.build import clang
from starboard.build import platform_configuration
from starboard.tools import build
from starboard.tools.testing import test_filter


class CreatorConfiguration(platform_configuration.PlatformConfiguration):
  """Starboard ci20 platform configuration."""

  def __init__(self, platform):
    super(CreatorConfiguration, self).__init__(platform)
    self.AppendApplicationConfigurationPath(os.path.dirname(__file__))

  def _GetCi20Home(self):
    try:
      ci20_home = os.environ['CI20_HOME']
    except KeyError:
      logging.critical('ci20 builds require the `CI20_HOME\' '
                       'environment variable to be set.')
      sys.exit(1)
    return ci20_home

  def GetVariables(self, config_name):
    relative_sysroot = os.path.join('sysroot')
    sysroot = os.path.join(self.ci20_home, relative_sysroot)

    if not os.path.isdir(sysroot):
      logging.critical(
          'ci20 builds require $CI20_HOME/%s to be a valid directory.',
          relative_sysroot)
      sys.exit(1)
    variables = super(CreatorConfiguration, self).GetVariables(
        config_name, use_clang=1)
    variables.update({
        'sysroot': sysroot,
        'javascript_engine': 'v8',
        'cobalt_enable_jit': 1,
        'v8_target_arch': 'mipsel',
        'mips_arch_variant': 'r2',
        'mips_fpu_mode': 'fp32',
        'mips_float_abi': 'hard',
    })

    return variables

  def GetLauncherPath(self):
    """Gets the path to the launcher module for this platform."""
    # Use launcher.py from src/starboard/linux/shared/
    linux_shared = os.path.join(
        os.path.dirname(__file__), '..', '..', '..', 'linux', 'shared')
    return linux_shared

  def GetGeneratorVariables(self, config_name):
    del config_name
    generator_variables = {
        'qtcreator_session_name_prefix': 'cobalt',
    }
    return generator_variables

  def GetEnvironmentVariables(self):
    self.ci20_home = self._GetCi20Home()
    if not hasattr(self, 'host_compiler_environment'):
      self.host_compiler_environment = build.GetHostCompilerEnvironment(
          clang.GetClangSpecification(), False)
    env_variables = self.host_compiler_environment
    env_variables = {
        'CC': self.host_compiler_environment['CC_host'],
        'CXX': self.host_compiler_environment['CXX_host'],
        'CC_host': 'gcc',
        'CXX_host': 'g++',
        'LD_host': 'g++',
        'ARFLAGS_host': 'rcs',
        'ARTHINFLAGS_host': 'rcsT',
    }

    return env_variables

  def GetTestFilters(self):
    filters = super(CreatorConfiguration, self).GetTestFilters()
    filters.extend([
        # test is disabled on x64
        test_filter.TestFilter('bindings_test',
                               ('GlobalInterfaceBindingsTest.'
                                'PropertiesAndOperationsAreOwnProperties')),
        # tests miss the defined delay
        test_filter.TestFilter('nplb',
                               'SbConditionVariableWaitTimedTest.SunnyDay'),
        test_filter.TestFilter(
            'nplb', 'SbConditionVariableWaitTimedTest.SunnyDayAutoInit'),
        # tests sometimes miss the threshold of 10ms
        test_filter.TestFilter(
            'nplb', 'Semaphore.ThreadTakesWait_PutBeforeTimeExpires'),
        test_filter.TestFilter('nplb', 'RWLock.HoldsLockForTime'),
        # tests sometimes miss the threshold of 5ms
        test_filter.TestFilter('nplb', 'Semaphore.ThreadTakesWait_TimeExpires'),
        test_filter.TestFilter('nplb', 'SbWindowCreateTest.SunnyDayDefault'),
        test_filter.TestFilter('nplb', 'SbWindowCreateTest.SunnyDayDefaultSet'),
        test_filter.TestFilter('nplb',
                               'SbWindowGetPlatformHandleTest.SunnyDay'),
        test_filter.TestFilter('nplb', 'SbWindowGetSizeTest.SunnyDay'),
        test_filter.TestFilter('nplb', 'SbPlayerTest.SunnyDay'),
        # tests fail also on x86
        test_filter.TestFilter(
            'nplb',
            ('SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.'
             'SunnyDayDestination/1')
        ),
        test_filter.TestFilter(
            'nplb',
            ('SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.'
             'SunnyDaySourceForDestination/1')
        ),
        test_filter.TestFilter(
            'nplb',
            ('SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.'
             'SunnyDaySourceNotLoopback/1')
        ),
        # there are no test cases in this test
        test_filter.TestFilter('nplb_blitter_pixel_tests',
                               test_filter.FILTER_ALL),
        # test fails on x64 also
        test_filter.TestFilter('net_unittests',
                               'HostResolverImplDnsTest.DnsTaskUnspec'),
    ])
    return filters
