#
# Copyright 2016 Google Inc. 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.
#
"""Functionality to enumerate and represent starboard ports."""

import logging
import os
import re

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

# The list of files that must be present in a directory to allow it to be
# considered a valid platform.
_PLATFORM_FILES = [
    'gyp_configuration.gypi',
    'gyp_configuration.py',
    'starboard_platform.gyp',
    'configuration_public.h',
    'atomic_public.h',
    'thread_types_public.h',
]


# Whether to emit warnings if it finds a directory that almost has a platform.
# TODO: Enable when tree is clean.
_WARN_ON_ALMOST = False


def _IsValidPlatformFilenameList(directory, filenames):
  """Determines if |filenames| contains the required files for a valid port."""
  missing = set(_PLATFORM_FILES) - set(filenames)
  if missing:
    if len(missing) < (len(_PLATFORM_FILES) / 2) and _WARN_ON_ALMOST:
      logging.warning('Directory %s contains several files needed for a '
                      'platform, but not all of them. In particular, it is '
                      'missing: %s', directory, ', '.join(missing))
  return not missing


def _GetPlatformName(root, directory):
  """Gets the name of a platform found at |directory| off of |root|."""
  assert directory.startswith(root)
  start = len(root) + 1  # Remove the trailing slash from the root.

  assert start < len(directory)

  # Calculate the name based on relative path from search root to directory.
  return re.sub(r'[^a-zA-Z0-9_]', r'-', directory[start:])


def _EnumeratePlatforms(root_path, exclusion_set=None):
  """Generator that iterates over Starboard platforms found under |path|."""
  if not exclusion_set:
    exclusion_set = set()

  for current_path, directories, filenames in os.walk(root_path):
    # Don't walk into any directories in the exclusion set.
    directories[:] = (x for x in directories
                      if os.path.join(current_path, x) not in exclusion_set)

    # Determine if the current directory is a valid port directory.
    if _IsValidPlatformFilenameList(current_path, filenames):
      if current_path == root_path:
        logging.warning('Found platform at search path root: %s', current_path)
      name = _GetPlatformName(root_path, current_path)
      yield PlatformInfo(name, current_path)


def _FindAllPlatforms():
  """Search the filesystem for all valid Starboard platforms.

  Returns:
    A Mapping of name->PlatformInfo.
  """

  result = {}
  search_path = environment.GetStarboardPortRoots()

  # Ignore search path directories inside other search path directories.
  exclusion_set = set(search_path)

  for entry in search_path:
    if not os.path.isdir(entry):
      continue
    for platform_info in _EnumeratePlatforms(entry, exclusion_set):
      if platform_info.name in result:
        logging.error('Found duplicate port name "%s" at "%s" and "%s"',
                      platform_info.name, result[platform_info.name],
                      platform_info.path)
      result[platform_info.name] = platform_info

  return result


# Cache of name->PlatformInfo mapping.
_INFO_MAP = None


def _GetInfoMap():
  """Gets mapping of platform names to PlatformInfo objects."""
  global _INFO_MAP
  if not _INFO_MAP:
    _INFO_MAP = _FindAllPlatforms()
  return _INFO_MAP


# Cache of the sorted list of all platform names.
_ALL = None


def GetAll():
  """Gets a sorted list of all valid Starboard platform names."""
  global _ALL
  if not _ALL:
    _ALL = sorted(_GetInfoMap().keys())
  return _ALL


def Get(platform_name):
  """Gets the PlatformInfo for the given platform name, or None."""
  return _GetInfoMap().get(platform_name)


def IsValid(platform_name):
  """Determines whether the given platform name is valid."""
  return platform_name in _GetInfoMap()


class PlatformInfo(object):
  """Information about a specific Starboard platform."""

  def __init__(self, name, path):
    self.name = name
    self.path = path
