#
# 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 importlib
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 port.
_PORT_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 port.
# TODO: Enable when tree is clean.
_WARN_ON_ALMOST_PORTS = False


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


def _GetPortName(root, directory):
  """Gets the name of a port 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 port.
  return re.sub(r'[^a-zA-Z0-9_]', r'-', directory[start:])


def _GetAllPlatforms(port_root_paths):
  """Retrieves information about all available Cobalt ports.

  Args:
    port_root_paths:  List of paths that will be crawled to find ports.

  Returns:
    Dict mapping each available port to its location in the filesystem.
  """
  platform_dict = {}
  for path in port_root_paths:
    for port in PlatformInfo.EnumeratePorts(path):
      platform_dict[port.port_name] = port.path
  return platform_dict


def GetAllPorts():
  """Gets all available starboard ports from the host app.

  Returns:
    Dictionary mapping port names to their path in the filesystem.
  """
  port_root_paths = environment.GetStarboardPortRoots()
  return _GetAllPlatforms(port_root_paths)


def GetAllNames():
  """Gets a list of all valid Starboard platform names.

  Returns:
    List of valid platform names.
  """
  return sorted(GetAllPorts().keys())


def IsValid(platform):
  return platform in GetAllNames()


class PlatformInfo(object):
  """Information about a specific starboard port."""

  @classmethod
  def EnumeratePorts(cls, root_path, exclusion_set=None):
    """Generator that iterates over starboard ports 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 _IsValidPortFilenameList(current_path, filenames):
        if current_path == root_path:
          logging.warning('Found port at search path root: %s', current_path)
        port_name = _GetPortName(root_path, current_path)
        yield PlatformInfo(port_name, current_path)

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

  def ImportModule(self, root_module, module_name=None):
    """Load a platform specific python module using importlib.

    Load the python module named |module_name| relative to |root_module|.
    Args:
      root_module: An already-loaded module
      module_name: Name of a python module to load. If None, load the platform
          directory as a python module.
    Returns:
      A module loaded with importlib.import_module
    Throws:
      ImportError if the module fails to be loaded.
    """
    # From the relative path to the |root_module|'s directory, construct a full
    # python package name and attempt to load it.
    relative_path = os.path.relpath(
        self.path, os.path.dirname(root_module.__file__))
    components = os.path.normpath(relative_path).split(os.sep)
    components = [root_module.__name__] + components
    if module_name:
      components.append(module_name)
    full_package_name = '.'.join(components)
    return importlib.import_module(full_package_name)
