# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Build target class and related functionality."""

import os
import re
from typing import Optional

from chromite.api.gen.chromiumos import common_pb2


class Error(Exception):
  """Base module error class."""


class InvalidNameError(Error):
  """Error for invalid target name argument."""


class BuildTarget(object):
  """Class to handle the build target information."""

  def __init__(self,
               name: str,
               profile: Optional[str] = None,
               build_root: Optional[str] = None):
    """Build Target init.

    Args:
      name: The full name of the target.
      profile: The profile name.
      build_root: The path to the buildroot.
    """
    if not name:
      raise InvalidNameError('Name is required.')

    self._name = name
    self.board, _, self.variant = name.partition('_')
    self.profile = profile

    if build_root:
      self.root = os.path.normpath(build_root)
    else:
      self.root = get_default_sysroot_path(self.name)

  def __eq__(self, other):
    if self.__class__ is other.__class__:
      return (self.name == other.name and self.profile == other.profile and
              self.root == other.root)

    return NotImplemented

  def __hash__(self):
    return hash(self.name)

  def __str__(self):
    return self.name

  @property
  def name(self):
    return self._name

  @property
  def as_protobuf(self):
    return common_pb2.BuildTarget(name=self.name)

  @classmethod
  def from_protobuf(cls, message):
    return cls(name=message.name)

  @property
  def profile_protobuf(self):
    return common_pb2.Profile(name=self.profile)

  def full_path(self, *args):
    """Turn a sysroot-relative path into an absolute path."""
    return os.path.join(self.root, *[part.lstrip(os.sep) for part in args])

  def get_command(self, base_command: str) -> str:
    """Get the build target's variant of the given base command.

    We create wrappers for many scripts that handle the build target's
    arguments. Build the target-specific variant for such a command.
    e.g. emerge -> emerge-eve.

    TODO: Add optional validation the command exists.

    Args:
      base_command: The wrapped command.

    Returns:
      The build target's command wrapper.
    """
    return '%s-%s' % (base_command, self.name)


def get_default_sysroot_path(build_target_name=None):
  """Get the default sysroot location or '/' if |build_target_name| is None."""
  if build_target_name is None:
    return '/'
  return os.path.join('/build', build_target_name)


def get_sdk_sysroot_path() -> str:
  """Get the SDK's sysroot path.

  Convenience/clarification wrapper for get_default_sysroot_path for use when
  explicitly fetching the SDK's sysroot path.
  """
  return get_default_sysroot_path()


def is_valid_name(build_target_name):
  """Validate |build_target_name| is a valid name."""
  return bool(re.match(r'^[a-zA-Z0-9-_]+$', build_target_name))
