#!/usr/bin/python

# Copyright 2017 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.
"""Extracts the API versions for all available builds.

  Example usage:
    cd cobalt/src/
    extract_starboard_versions.py
"""

from __future__ import print_function

import os
import re
import sys

import _env  # pylint: disable=unused-import
from starboard.tools import paths
from starboard.tools import platform


# Sometimes files have weird encodings. This function will use a variety of
# hand selected encoders that work on the starboard codebase.
def AutoDecodeString(file_data):
  for encoding in {'UTF-8', 'utf_16', 'windows-1253', 'iso-8859-7', 'macgreek'}:
    try:
      return file_data.decode(encoding)
    except ValueError:
      continue
  raise IOError('Could not read file')


# Given a search_term, this will open the file_path and return the first
# line that contains the search term. This will ignore C-style comments.
def SearchInFileReturnFirstMatchingLine(file_path, search_term):
  try:
    lines = OpenFileAndDecodeLinesAndRemoveComments(file_path)
    for line in lines:
      if search_term in line:
        return line
    return None
  except IOError:
    print('  error while reading file ', file_path)


# Opens a header or cc file and decodes it to utf8 using a variety
# of decoders. All lines will have their comments stripped out.
# This will return the lines of the given file.
def OpenFileAndDecodeLinesAndRemoveComments(file_path):
  with open(file_path, 'rb+') as fd:
    lines = AutoDecodeString(fd.read()).splitlines()
    # remove c-style comments.
    lines = [re.sub('//.*', '', line) for line in lines]
    return lines


def FindIncludeFiles(file_path):
  """Given a file_path, return all include files that it contains."""
  try:
    output_list = []
    lines = OpenFileAndDecodeLinesAndRemoveComments(file_path)
    for line in lines:
      # Remove c-style comments.
      if '#include' in line:
        line = re.sub('#include ', '', line).replace('"', '')
        output_list.append(line)
    return output_list
  except IOError:
    print('  error while reading file ', file_path)


# Searches from the search_location for a configuration.h file that
# contains the definition of the SB_EXPERIMENTAL_API_VERSION and then
# returns that as type int.
def ExtractExperimentalApiVersion(config_file_path):
  """Searches for and extracts the current experimental API version."""
  needle = '#define SB_EXPERIMENTAL_API_VERSION'
  line = SearchInFileReturnFirstMatchingLine(
      config_file_path, '#define SB_EXPERIMENTAL_API_VERSION')
  if not line:
    raise ValueError('Could not find ' + needle + ' in ' + config_file_path)

  elements = line.split(' ')
  exp_api_version = int(elements[2])
  return exp_api_version


# Given platform path, this function will try and find the version. Returns
# either the version if found, or None.
# If the version string is returned, note that it could be
# 'SB_EXPERIMENTAL_VERSION' or a number string.
def FindVersion(platform_path):
  api_version_str = '#define SB_API_VERSION'
  result = SearchInFileReturnFirstMatchingLine(platform_path, api_version_str)
  if not result:
    return None
  version_str = result.replace(api_version_str, '')
  return version_str.strip()


# Given the path to the platform_include_file, this will find the include
# files with "configuration_public.h" in the name and return those.
def FindConfigIncludefile(platform_path_config_file):
  include_files = FindIncludeFiles(platform_path_config_file)
  include_files = [x for x in include_files if 'configuration_public.h' in x]
  return include_files


def GeneratePlatformPathMap():
  """Return a map of platform-name -> full-path-to-platform-config-header."""

  def GenPath(p):
    full_path = os.path.abspath(os.path.join(p.path, 'configuration_public.h'))
    if not os.path.exists(full_path):
      raise IOError('Could not find path ' + full_path)
    return full_path

  return {p.name: GenPath(p) for p in platform.GetAllInfos()}


# Given the root starboard directory, and the full path to the platform,
# this function will search for the API_VERSION of the platform. It will
# first see if the version is defined within the include file, if it is
# not then the include paths for shared platform configurations are
# searched in the recursive step.
def FindVersionRecursive(starboard_dir, platform_path):
  version_str = FindVersion(platform_path)
  if version_str:
    return version_str
  else:
    config_include_paths = FindConfigIncludefile(platform_path)
    if not config_include_paths:
      return '<UNKNOWN>'
    elif len(config_include_paths) > 1:
      return '<AMBIGUOUS>'
    else:
      include_path = config_include_paths[0]
      include_path = re.sub(r'^starboard/', '', include_path)
      full_include_path = os.path.join(starboard_dir, include_path)
      return FindVersionRecursive(starboard_dir, full_include_path)


def Main():
  """Prints the API versions of all known ports."""
  print('\n***** Listing the API versions of all known ports. *****\n')

  port_dict = GeneratePlatformPathMap()

  experimental_api_version = ExtractExperimentalApiVersion(
      os.path.join(paths.STARBOARD_ROOT, 'configuration.h'))

  path_map = {}

  print('Experimental API Version: ' + str(experimental_api_version) + '\n')

  for platform_name, platform_path in port_dict.iteritems():
    version_str = FindVersionRecursive(paths.STARBOARD_ROOT, platform_path)
    if 'SB_EXPERIMENTAL_API_VERSION' in version_str:
      version_str = str(experimental_api_version)
    path_map[platform_name] = version_str

  for platform_name, api_version in sorted(path_map.iteritems()):
    print(platform_name + ': ' + api_version)

  return 0


if __name__ == '__main__':
  # All functionality stored in Main() to avoid py-lint from warning about
  # about shadowing global variables in local functions.
  sys.exit(Main())
