#!/usr/bin/env python
# Copyright (c) 2013 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.

import argparse
import glob
import os
import shutil
import subprocess
import sys


# Define default the version of libchrome{,os} to build against.
# Used only if the BASE_VER environment variable is not set.
# This can also be overridden in a specific target GYP file if required.
_BASE_VER = '242728'


class Platform2(object):
  def __init__(self, use_flags, board=None, host=False, libdir=None,
               incremental=True, verbose=False, enable_tests=False):
    self.board = board
    self.host = host
    self.incremental = incremental
    self.verbose = verbose

    if use_flags:
      self.use_flags = use_flags
    else:
      self.use_flags = self.get_platform2_use_flags()

    if enable_tests:
      self.use_flags.add('test')

    if self.host:
      self.arch = self.get_portageq_envvars('ARCH')
      self.sysroot = '/'
      self.pkgconfig = 'pkg-config'
    else:
      board_vars = self.get_portageq_envvars(['ARCH', 'SYSROOT', 'PKG_CONFIG'],
                                             board=board)

      self.arch = board_vars['ARCH']
      self.sysroot = board_vars['SYSROOT']
      self.pkgconfig = board_vars['PKG_CONFIG']

    if libdir:
      self.libdir = libdir
    else:
      self.libdir = '/usr/lib64' if self.arch == 'amd64' else '/usr/lib'

  def get_src_dir(self):
    """Return the path to build tools and common GYP files"""

    return os.path.realpath(os.path.dirname(__file__))

  def get_platform2_root(self):
    """Return the path to src/platform2"""

    return os.path.dirname(self.get_src_dir())

  def get_platform_root(self):
    """Return the path to src/platform"""

    return os.path.normpath(os.path.join(
        self.get_src_dir(), '..', '..', 'platform'));

  def get_buildroot(self):
    """Return the path to the folder where build artifacts are located."""
    if not self.incremental:
      workdir = os.environ.get('WORKDIR')
      if workdir:
        # Matches $(cros-workon_get_build_dir) behavior.
        return os.path.join(workdir, 'build')
      else:
        return os.getcwd()
    else:
      return os.path.join(self.sysroot,
                          'var/cache/portage/chromeos-base/platform2/')

  def get_products_path(self):
    """Return the path to the folder where build product are located."""

    return os.path.join(self.get_buildroot(), 'out/Default')

  def get_portageq_envvars(self, varnames, board = None):
    """Returns the values of a given set of variables using portageq."""
    if isinstance(varnames, basestring):
      varnames = [varnames]

    if board is None and not self.host:
      board = self.board

    portageq_bin = 'portageq' if not board else 'portageq-' + board
    cmd = [portageq_bin, 'envvar', '-v']
    cmd += varnames

    try:
      p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      output, errors = p.communicate()
    except UnboundLocalError:
      raise AssertionError('Error running ' + portageq_bin)
    except OSError:
      raise AssertionError('Error running portageq: ' + errors)

    output_lines = [x for x in output.splitlines() if x]
    output_items = [x.split('=', 1) for x in output_lines]
    board_vars = dict(dict([(k, v[1:-1]) for k, v in output_items]))

    return board_vars if len(board_vars) > 1 else board_vars.values()[0]

  def get_platform2_use_flags(self):
    """Returns the set of USE flags set for the Platform2 package."""
    equery_bin = 'equery' if not self.board else 'equery-' + self.board
    cmd = [equery_bin, 'u', 'platform2']

    try:
      p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      output, errors = p.communicate()
    except UnboundLocalError:
      raise AssertionError('Error running ' + equery_bin)
    except OSError:
      raise AssertionError('Error running equery: ' + errors)

    return set([x for x in output.splitlines() if x])

  def get_build_environment(self):
    """Returns a dict containing environment variables we will use to run GYP.

    We do this to set the various CC/CXX/AR names for the target board."""

    board_env = self.get_portageq_envvars(['CHOST', 'AR', 'CC', 'CXX'])

    tool_names = {
      'AR': 'ar',
      'CC': 'gcc',
      'CXX': 'g++',
    }

    env = os.environ.copy()
    for var, tool in tool_names.items():
      env[var + '_target'] = board_env[var] if board_env[var] else \
                             board_env['CHOST'] + '-' + tool

    return env

  def get_components_glob(self):
    """Return a glob of marker files for components/projects that were built.

    Each project spits out a file whilst building: we return a glob of them
    so we can install/test those projects or reset between compiles to ensure
    components that are no longer part of the build don't get installed."""

    return glob.glob(os.path.join(self.get_products_path(),
                                  'gen/components_*'))

  def use(self, flag):
    """Returns a boolean describing whether or not a given USE flag is set."""

    return flag in self.use_flags

  def configure(self, args):
    """Runs the configure step of the Platform2 build.

    Creates the build root if it doesn't already exists. Generates flags to
    run GYP with, and then runs GYP."""

    if not os.path.isdir(self.get_buildroot()):
      os.makedirs(self.get_buildroot())

    if not self.incremental and os.path.isdir(self.get_products_path()):
      shutil.rmtree(self.get_products_path())

    gyp_files = {
      'platform': os.path.join(self.get_src_dir(), 'platform.gyp'),
      'common': os.path.join(self.get_src_dir(), 'common.gypi')
    }

    # The common root folder of platform/ and platform2/.
    # Used as (DEPTH) variable in specific project .gyp files.
    src_root = os.path.normpath(os.path.join(self.get_src_dir(), '..', '..'));

    # Do NOT pass the board name into GYP. If you think you need to so, you're
    # probably doing it wrong.
    gyp_args = [
      'gyp',
      gyp_files['platform'],
      '--format=ninja',
      '--include=' + gyp_files['common'],
      '--depth=' + src_root,
      '--toplevel-dir=' + self.get_platform2_root(),
      '--generator-output=' + self.get_buildroot(),
      '-Dpkg-config=' + self.pkgconfig,
      '-Dsysroot=' + self.sysroot,
      '-Dlibdir=' + self.libdir,
      '-Dplatform_root=' + self.get_platform_root(),
      '-Dplatform2_root=' + self.get_platform2_root(),
      '-Dlibbase_ver=' + os.environ.get('BASE_VER', _BASE_VER),
      '-Dclang_syntax=' + os.environ.get('CROS_WORKON_CLANG', ''),
      '-Dexternal_cflags=' + os.environ.get('CFLAGS', ''),
      '-Dexternal_cxxflags=' + os.environ.get('CXXFLAGS', ''),
      '-Dexternal_ldflags=' + os.environ.get('LDFLAGS', ''),
    ]
    gyp_args += ['-DUSE_%s=1' % (use_flag,) for use_flag in self.use_flags]

    try:
      subprocess.check_call(gyp_args, env=self.get_build_environment(),
                            cwd=self.get_platform2_root())
    except subprocess.CalledProcessError:
      raise AssertionError('Error running: %s'
                           % ' '.join(map(repr, gyp_args)))

  def compile(self, args):
    """Runs the compile step of the Platform2 build.

    Removes any existing component markers that may exist (so we don't run
    tests/install for projects that have been disabled since the last
    build). Builds arguments for running Ninja and then runs Ninja."""

    for component in self.get_components_glob():
      os.remove(component)

    env = os.environ.copy()
    env['PATH'] += ':/mnt/host/depot_tools'

    if not args:
      args = ['all']
    ninja_args = ['ninja', '-C', self.get_products_path()] + args

    if self.verbose:
      ninja_args.append('-v')

    try:
      subprocess.check_call(ninja_args, env=env)
    except subprocess.CalledProcessError:
      raise AssertionError('Error running: %s'
                           % ' '.join(map(repr, ninja_args)))

  def deviterate(self, args):
    """Runs the configure and compile steps of the Platform2 build.

    This is the default action, to allow easy iterative testing of changes
    as a developer."""

    self.configure([])
    self.compile(args)


class _ParseStringSetAction(argparse.Action):
  def __call__(self, parser, namespace, values, option_string=None):
    setattr(namespace, self.dest, set(values.split()))


def main(argv):
  actions = ['configure', 'compile', 'deviterate']

  parser = argparse.ArgumentParser()
  parser.add_argument('--action', default='deviterate',
                      choices=actions, help='action to run')
  parser.add_argument('--board',
                      help='board to build for')
  parser.add_argument('--disable_incremental', action='store_false',
                      dest='incremental', help='disable incremental build')
  parser.add_argument('--enable_tests', action='store_true',
                      help='build and run tests')
  parser.add_argument('--host', action='store_true',
                      help='specify that we\'re building for the host')
  parser.add_argument('--libdir',
                      help='the libdir for the specific board, eg /usr/lib64')
  parser.add_argument('--use_flags',
                      action=_ParseStringSetAction, help='USE flags to enable')
  parser.add_argument('--verbose', action='store_true', default=None,
                      help='enable verbose log output')
  parser.add_argument('args', nargs='*')

  options = parser.parse_args(argv)

  if not (options.host ^ (options.board != None)):
    raise AssertionError('You must provide only one of --board or --host')

  if options.verbose is None:
    # Should convert to cros_build_lib.BooleanShellValue.
    options.verbose = (os.environ.get('VERBOSE', '0') == '1')

  p2 = Platform2(options.use_flags, options.board, options.host,
                 options.libdir, options.incremental, options.verbose,
                 options.enable_tests)
  getattr(p2, options.action)(options.args)


if __name__ == '__main__':
  main(sys.argv[1:])
