# 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 Android shared platform configuration for gyp_cobalt."""

from __future__ import print_function

import imp
import os
import subprocess

from starboard.android.shared import sdk_utils
from starboard.build import clang as clang_build
from starboard.build.platform_configuration import PlatformConfiguration
from starboard.tools import build
from starboard.tools.testing import test_filter
from starboard.tools.toolchain import ar
from starboard.tools.toolchain import bash
from starboard.tools.toolchain import clang
from starboard.tools.toolchain import clangxx
from starboard.tools.toolchain import cp
from starboard.tools.toolchain import touch

_APK_DIR = os.path.join(os.path.dirname(__file__), os.path.pardir, 'apk')
_APK_BUILD_ID_FILE = os.path.join(_APK_DIR, 'build.id')
_COBALT_GRADLE = os.path.join(_APK_DIR, 'cobalt-gradle.sh')

# The API level of NDK tools to use. This should be the minimum API level on
# which the app is expected to run. If some feature from a newer NDK level is
# needed, this may be increased with caution.
# https://developer.android.com/ndk/guides/stable_apis.html
#
# Using 24 will lead to missing symbols on API 23 devices.
# https://github.com/android-ndk/ndk/issues/126
_ANDROID_NDK_API_LEVEL = '21'

# Maps the Android ABI to the clang & ar executable names.
_ABI_TOOL_NAMES = {
    'x86': ('i686-linux-android{}-clang'.format(_ANDROID_NDK_API_LEVEL),
            'i686-linux-android-ar'),
    'x86_64': ('x86_64-linux-android{}-clang'.format(_ANDROID_NDK_API_LEVEL),
               'x86_64-linux-android-ar'),
    'armeabi':
        ('armv7a-linux-androideabi{}-clang'.format(_ANDROID_NDK_API_LEVEL),
         'armv7a-linux-androideabi-ar'),
    'armeabi-v7a':
        ('armv7a-linux-androideabi{}-clang'.format(_ANDROID_NDK_API_LEVEL),
         'arm-linux-androideabi-ar'),
    'arm64-v8a':
        ('aarch64-linux-android{}-clang'.format(_ANDROID_NDK_API_LEVEL),
         'aarch64-linux-android-ar'),
}


class AndroidConfiguration(PlatformConfiguration):
  """Starboard Android platform configuration."""

  # TODO: make ASAN work with NDK tools and enable it by default
  def __init__(self,
               platform,
               android_abi,
               asan_enabled_by_default=False,
               sabi_json_path=None):
    super(AndroidConfiguration, self).__init__(platform,
                                               asan_enabled_by_default)
    self._target_toolchain = None
    self._host_toolchain = None

    self.AppendApplicationConfigurationPath(os.path.dirname(__file__))

    self.android_abi = android_abi
    self.sabi_json_path = sabi_json_path

    self.android_home = sdk_utils.GetSdkPath()
    self.android_ndk_home = sdk_utils.GetNdkPath()

    print('Using Android SDK at {}'.format(self.android_home))
    print('Using Android NDK at {}'.format(self.android_ndk_home))

  def GetBuildFormat(self):
    """Returns the desired build format."""
    # The comma means that ninja and qtcreator_ninja will be chained and use the
    # same input information so that .gyp files will only have to be parsed
    # once.
    return 'ninja,qtcreator_ninja'

  def GetVariables(self, configuration):
    variables = super(AndroidConfiguration, self).GetVariables(
        configuration, use_clang=1)
    variables.update({
        'ANDROID_HOME':
            self.android_home,
        'NDK_HOME':
            self.android_ndk_home,
        'ANDROID_ABI':
            self.android_abi,
        'include_path_platform_deploy_gypi':
            'starboard/android/shared/platform_deploy.gypi',
        'javascript_engine':
            'v8',
        'cobalt_enable_jit':
            1,
    })
    return variables

  def GetDeployPathPatterns(self):
    """example src/out/android-arm64/devel/cobalt.apk"""
    return ['*.apk']

  def GetGeneratorVariables(self, configuration):
    _ = configuration
    generator_variables = {
        'qtcreator_session_name_prefix': 'cobalt',
    }
    return generator_variables

  def SetupPlatformTools(self, build_number):
    sdk_utils.InstallSdkIfNeeded()
    subprocess.call([_COBALT_GRADLE, '--reset'])
    with open(_APK_BUILD_ID_FILE, 'w') as build_id_file:
      build_id_file.write('{}'.format(build_number))

  def GetEnvironmentVariables(self):
    env_variables = {}

    # Android builds tend to consume significantly more memory than the
    # default settings permit, so cap this at 1 in order to avoid build
    # issues.  Without this, 32GB machines end up getting automatically
    # configured to run 5 at a time, which can be too much for at least
    # android-arm64_debug.
    # TODO: Eventually replace this with something more robust, like an
    #       implementation of the abstract toolchain for Android.
    env_variables.update({'GYP_LINK_CONCURRENCY': '1'})

    return env_variables

  def GetTargetToolchain(self):
    if not self._target_toolchain:
      tool_prefix = os.path.join(sdk_utils.GetNdkPath(), 'toolchains', 'llvm',
                                 'prebuilt', 'linux-x86_64', 'bin', '')
      cc_path = tool_prefix + _ABI_TOOL_NAMES[self.android_abi][0]
      cxx_path = cc_path + '++'
      ar_path = tool_prefix + _ABI_TOOL_NAMES[self.android_abi][1]
      clang_flags = [
          # We'll pretend not to be Linux, but Starboard instead.
          '-U__linux__',

          # libwebp uses the cpufeatures library to detect ARM NEON support
          '-I{}/sources/android/cpufeatures'.format(self.android_ndk_home),

          # Mimic build/cmake/android.toolchain.cmake in the Android NDK.
          '-ffunction-sections',
          '-funwind-tables',
          '-fstack-protector-strong',
          '-no-canonical-prefixes',

          # Other flags
          '-fsigned-char',
          '-fno-limit-debug-info',
          '-fno-exceptions',
          '-fcolor-diagnostics',
          '-fno-strict-aliasing',  # See http://crbug.com/32204

          # Default visibility is hidden to enable dead stripping.
          '-fvisibility=hidden',
          # Any warning will stop the build.
          '-Werror',

          # Disable errors for the warning till the Android NDK r19 is fixed.
          # The warning is trigger when compiling .c files and complains for
          # '-stdlib=libc++' which is added by the NDK.
          '-Wno-error=unused-command-line-argument',

          # Don't warn about register variables (in base and net)
          '-Wno-deprecated-register',
          # Don't warn about deprecated ICU methods (in googleurl and net)
          '-Wno-deprecated-declarations',
          # Skia doesn't use overrides.
          '-Wno-inconsistent-missing-override',
          # shifting a negative signed value is undefined
          '-Wno-shift-negative-value',
          # Don't warn for implicit sign conversions. (in v8 and protobuf)
          '-Wno-sign-conversion',
      ]
      clang_defines = [
          # Enable compile-time decisions based on the ABI
          'ANDROID_ABI={}'.format(self.android_abi),
          # -DANDROID is an argument to some ifdefs in the NDK's eglplatform.h
          'ANDROID',
          # Cobalt on Linux flag
          'COBALT_LINUX',
          # So that we get the PRI* macros from inttypes.h
          '__STDC_FORMAT_MACROS',
          # Enable GNU extensions to get prototypes like ffsl.
          '_GNU_SOURCE=1',
          # Undefining __linux__ causes the system headers to make wrong
          # assumptions about which C-library is used on the platform.
          '__BIONIC__',
          # Undefining __linux__ leaves libc++ without a threads implementation.
          # TODO: See if there's a way to make libcpp threading use Starboard.
          '_LIBCPP_HAS_THREAD_API_PTHREAD',
      ]
      linker_flags = [
          # Use the static LLVM libc++.
          '-static-libstdc++',

          # Mimic build/cmake/android.toolchain.cmake in the Android NDK, but
          # force build-id to sha1, so that older lldb versions can still find
          # debugsymbols, see https://github.com/android-ndk/ndk/issues/885
          '-Wl,--build-id=sha1',
          '-Wl,--warn-shared-textrel',
          '-Wl,--fatal-warnings',
          '-Wl,--gc-sections',
          '-Wl,-z,nocopyreloc',

          # Wrapper synchronizes punch-out video bounds with the UI frame.
          '-Wl,--wrap=eglSwapBuffers',
      ]
      self._target_toolchain = [
          clang.CCompiler(
              path=cc_path, defines=clang_defines, extra_flags=clang_flags),
          clang.CxxCompiler(
              path=cxx_path,
              defines=clang_defines,
              extra_flags=clang_flags + [
                  '-std=c++11',
              ]),
          clang.AssemblerWithCPreprocessor(
              path=cc_path, defines=clang_defines, extra_flags=clang_flags),
          ar.StaticThinLinker(path=ar_path),
          ar.StaticLinker(path=ar_path),
          clangxx.SharedLibraryLinker(path=cxx_path, extra_flags=linker_flags),
          clangxx.ExecutableLinker(path=cxx_path, extra_flags=linker_flags),
      ]
    return self._target_toolchain

  def GetHostToolchain(self):
    if not self._host_toolchain:
      if not hasattr(self, 'host_compiler_environment'):
        self.host_compiler_environment = build.GetHostCompilerEnvironment(
            clang_build.GetClangSpecification(), False)
      cc_path = self.host_compiler_environment['CC_host'],
      cxx_path = self.host_compiler_environment['CXX_host']
      self._host_toolchain = [
          clang.CCompiler(path=cc_path),
          clang.CxxCompiler(path=cxx_path),
          clang.AssemblerWithCPreprocessor(path=cc_path),
          ar.StaticThinLinker(),
          ar.StaticLinker(),
          clangxx.ExecutableLinker(path=cxx_path),
          clangxx.SharedLibraryLinker(path=cxx_path),
          cp.Copy(),
          touch.Stamp(),
          bash.Shell(),
      ]
    return self._host_toolchain

  def GetLauncher(self):
    """Gets the module used to launch applications on this platform."""
    module_path = os.path.abspath(
        os.path.join(os.path.dirname(__file__), 'launcher.py'))
    launcher_module = imp.load_source('launcher', module_path)
    return launcher_module

  def GetTestFilters(self):
    filters = super(AndroidConfiguration, self).GetTestFilters()
    for target, tests in self.__FILTERED_TESTS.iteritems():
      filters.extend(test_filter.TestFilter(target, test) for test in tests)
    return filters

  # A map of failing or crashing tests per target.
  __FILTERED_TESTS = {  # pylint: disable=invalid-name
      'player_filter_tests': [
          # Filter flaky failed tests temporarily.
          'VideoDecoderTests/VideoDecoderTest.SingleInput/0',
          'VideoDecoderTests/VideoDecoderTest.SingleInput/2',
          'VideoDecoderTests/VideoDecoderTest.SingleInput/4',
          'VideoDecoderTests/VideoDecoderTest.SingleInput/6',
          'VideoDecoderTests/VideoDecoderTest.ResetBeforeInput/0',
          'VideoDecoderTests/VideoDecoderTest.ResetBeforeInput/2',
          'VideoDecoderTests/VideoDecoderTest.ResetBeforeInput/4',
          'VideoDecoderTests/VideoDecoderTest.ResetBeforeInput/6',
          'VideoDecoderTests/VideoDecoderTest.MultipleResets/0',
          'VideoDecoderTests/VideoDecoderTest.MultipleResets/2',
          'VideoDecoderTests/VideoDecoderTest.MultipleResets/4',
          'VideoDecoderTests/VideoDecoderTest.MultipleResets/6',
          'VideoDecoderTests/VideoDecoderTest.MultipleInputs/0',
          'VideoDecoderTests/VideoDecoderTest.MultipleInputs/2',
          'VideoDecoderTests/VideoDecoderTest.MultipleInputs/4',
          'VideoDecoderTests/VideoDecoderTest.MultipleInputs/6',
          'VideoDecoderTests/VideoDecoderTest.Preroll/0',
          'VideoDecoderTests/VideoDecoderTest.Preroll/2',
          'VideoDecoderTests/VideoDecoderTest.Preroll/4',
          'VideoDecoderTests/VideoDecoderTest.Preroll/6',
          'VideoDecoderTests/VideoDecoderTest.DecodeFullGOP/0',
          'VideoDecoderTests/VideoDecoderTest.DecodeFullGOP/2',
          'VideoDecoderTests/VideoDecoderTest.DecodeFullGOP/4',
          'VideoDecoderTests/VideoDecoderTest.DecodeFullGOP/6',

          # GetMaxNumberOfCachedFrames() on Android is device dependent,
          # and Android doesn't provide an API to get it. So, this function
          # doesn't make sense on Android. But HoldFramesUntilFull tests depend
          # on this number strictly.
          'VideoDecoderTests/VideoDecoderTest.HoldFramesUntilFull/*',

          # Currently, invalid input tests are not supported.
          'VideoDecoderTests/VideoDecoderTest.SingleInvalidInput/*',
          'VideoDecoderTests/VideoDecoderTest'
          '.MultipleValidInputsAfterInvalidKeyFrame/*',
          'VideoDecoderTests/VideoDecoderTest.MultipleInvalidInput/*',

          # Android currently does not support multi-video playback, which
          # the following tests depend upon.
          'VideoDecoderTests/VideoDecoderTest.ThreeMoreDecoders/*',
      ],
      'nplb': [
          # This test is failing because localhost is not defined for IPv6 in
          # /etc/hosts.
          'SbSocketAddressTypes/SbSocketResolveTest.Localhost/1',
      ],
  }

  def GetPathToSabiJsonFile(self):
    return self.sabi_json_path
