#!/usr/bin/env python3
# Copyright 2020 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.

# This file uses 2-space indentations.
# pylint: disable=bad-indentation

# This is contrib-quality code: not all functions/classes are
# documented.
# pylint: disable=missing-function-docstring
# pylint: disable=missing-class-docstring
# pylint: disable=class-missing-docstring

# Classes make heavy-use of setattr to dynamically set the attributes
# on an object.  Disable this check which gets confused very
# frequently.
# pylint: disable=no-member

"""Utility script to auto-convert a pre-unibuild board to unibuild."""

import argparse
import datetime
import json
import os
import pathlib
import re
import shlex
import subprocess
import sys
import tempfile
# pylint: disable=import-error
import yaml
# pylint: enable=import-error


make_defaults_search_and_destroy_re = re.compile(
    r'(?:^\s*)*(?:^\s*#.*\s*)*^\s*USE="\s*\$\{?USE\}?\s*-unibuild\s*"\s*$',
    re.MULTILINE)


def log(message):
  print('[{}] {}'.format(datetime.datetime.now(), message), file=sys.stderr)


def prepend_all_lines(text, prepend):
  return ''.join(
      '{}{}\n'.format(prepend, line)
      for line in text.splitlines())


def gen_cros_copyright(line_comment='# '):
  return prepend_all_lines(
      """Copyright {} 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.""".format(datetime.datetime.now().strftime('%Y')),
      line_comment)


def yaml_str_representer(dumper, data):
  style = None
  tag = 'tag:yaml.org,2002:str'
  if '\n' in data:
    style = '|'
  return dumper.represent_scalar(tag, data, style)


yaml.add_representer(str, yaml_str_representer)


def format_yaml(config, device_configs, used_vars):
  conf_str = yaml.dump(config, indent=2, default_flow_style=False)
  out = gen_cros_copyright()
  out += """
device-config: &device_config\n"""
  out += prepend_all_lines(conf_str, '  ')
  out += """
chromeos:
  devices:\n"""
  for dev in device_configs:
    out += "    - "
    for var in used_vars:
      out += "${}: {}\n".format(var, getattr(dev, var))
      out += "      "
    out += """skus:
        - config: *device_config\n"""
  return out


def generate_bsp_ebuild(private=False):
  return gen_cros_copyright() + """
EAPI=7

# cros_workon applies only to ebuild and files directory. Use the
# canonical empty project.
CROS_WORKON_PROJECT="chromiumos/infra/build/empty-project"
CROS_WORKON_LOCALNAME="platform/empty-project"

inherit cros-workon cros-unibuild

DESCRIPTION="ChromeOS model configuration"
HOMEPAGE="https://chromium.googlesource.com/chromiumos/platform2/+/master/chromeos-config/README.md"

LICENSE="BSD-Google"
SLOT="0"
KEYWORDS="~*"

src_install() {
\tinstall%(maybe_private)s_model_files
}
""" % {'maybe_private': '_private' if private else ''}


def generate_firmware_ebuild(board_name):
  return gen_cros_copyright() + """
# Change this version number when any change is made to model.yaml
# in order to trigger an auto-revbump is required.
# VERSION=REVBUMP-0.0.1

EAPI=7
CROS_WORKON_COMMIT=""
CROS_WORKON_TREE=""
CROS_WORKON_LOCALNAME="platform/firmware"
CROS_WORKON_PROJECT="chromiumos/platform/firmware"

inherit cros-workon cros-firmware cros-unibuild

DESCRIPTION="Chrome OS Firmware (%(board_name)s)"
HOMEPAGE="http://src.chromium.org"
LICENSE="BSD-Google"
SLOT="0"
KEYWORDS="~*"

RDEPEND=""

# Unified Builds firmware URL's are read from:
#   chromeos-base/chromeos-config-bsp-private/files/model.yaml
# in this repository. Those config files output the SRC_URI's used by Portage.
#
# Update the model.yaml, then run this command from the
# src/platform/dev/contrib directory:
#
#   ./cros_update_firmware --board=%(board_name)s
#
# Verify the changes by running:
#   /build/%(board_name)s/usr/sbin/chromeos-firmwareupdate --manifest
#
# If this works then you can create a CL with your changes, which should include
# the files:
# chromeos-base/chromeos-config-bsp-private/files/model.yaml
# chromeos-base/chromeos-firmware-%(board_name)s/Manifest
# chromeos-base/chromeos-firmware-%(board_name)s/files/srcuris
# chromeos-base/chromeos-firmware-%(board_name)s/chromeos-firmware-%(board_name)s-9999.ebuild
cros-firmware_setup_source
""" % {'board_name': board_name}


def find_file(searchdir, name):
  results = []
  for root, _, files in os.walk(searchdir):
    if name in files:
      results.append(pathlib.Path(root) / name)
  return results


def find_one_file(searchdir, name):
  results = find_file(searchdir, name)
  assert len(results) == 1
  return results.pop()


def sh_getvar(script, varname):
  script = script + ('\necho "${%s}"\n' % varname)
  with tempfile.NamedTemporaryFile('w') as f:
    f.write(script)
    f.flush()
    res = subprocess.run(['sh', f.name], stdout=subprocess.PIPE,
                         check=True, encoding='utf-8')
  return res.stdout.strip() or None


def write_file(fullpath, file_contents):
  os.makedirs(fullpath.parent, exist_ok=True)
  log('Writing {}...'.format(fullpath))
  with open(fullpath, 'w') as f:
    f.write(file_contents)


def generate_make_defaults(contents, private=False):
  contents = make_defaults_search_and_destroy_re.sub('', contents)
  bsp_use_flag = 'has_chromeos_config_bsp'
  if private:
    bsp_use_flag += '_private'
  contents += """
# Enable chromeos-config.
USE="${USE} unibuild %(bsp_use_flag)s"
""" % dict(bsp_use_flag=bsp_use_flag)
  return contents


class CrosConfig:
  def __init__(self, public_yaml_raw, private_yaml_raw):
    with tempfile.NamedTemporaryFile(mode='w', delete=False) as merged_tempfile, \
         tempfile.NamedTemporaryFile(mode='w') as public_yaml_tempfile, \
         tempfile.NamedTemporaryFile(mode='w') as private_yaml_tempfile:
      public_yaml_tempfile.write(public_yaml_raw)
      public_yaml_tempfile.flush()

      private_yaml_tempfile.write(private_yaml_raw)
      private_yaml_tempfile.flush()

      log('Merging and validating config schema...')
      subprocess.run(['cros_config_schema', '-o', merged_tempfile.name,
                      '-m', public_yaml_tempfile.name,
                      private_yaml_tempfile.name], check=True)
      self.merged_yaml = merged_tempfile.name

  def run_host_command(self, *args):
    return subprocess.run(['cros_config_host', '-c', self.merged_yaml]
                          + list(args),
                          check=True, encoding='utf-8',
                          stdout=subprocess.PIPE).stdout


class BoardOverlays:
  FIRMWARE_ATTRS = [
      ('CROS_FIRMWARE_MAIN_IMAGE', 'bcs_main_ro'),
      ('CROS_FIRMWARE_MAIN_RW_IMAGE', 'bcs_main_rw'),
      ('CROS_FIRMWARE_EC_IMAGE', 'bcs_ec'),
      ('CROS_FIRMWARE_PD_IMAGE', 'bcs_pd'),
  ]

  MAKE_DEFAULTS_ATTRS = [
      ('EC_FIRMWARE', 'ec_firmwares'),
      ('PD_FIRMWARE', 'pd_firmwares'),
      ('EC_FIRMWARE_EXTRA', 'ec_firmware_extras'),
      ('FPMCU_FIRMWARE', 'fpmcu_firmware'),
      ('USE', 'use_flags'),
  ]

  def __init__(self, board_name, checkout, mosys_platform):
    self.checkout = checkout
    self.board_name = board_name
    self.mosys_platform = mosys_platform
    self.public_overlay = (checkout / 'src' / 'overlays'
                           / f'overlay-{board_name}')
    log('Public overlay path: {}'.format(self.public_overlay))
    self.private_overlay = (checkout / 'src' / 'private-overlays'
                            / f'overlay-{board_name}-private')
    log('Private overlay path: {}'.format(self.private_overlay))

    assert self.public_overlay.is_dir()
    assert self.private_overlay.is_dir()

    # Find the firmware ebuild
    self.firmware_ebuild_path = find_one_file(
        self.private_overlay, f'chromeos-firmware-{board_name}-9999.ebuild')
    log('Firmware ebuild path: {}'.format(self.firmware_ebuild_path))

    # Read the firmware attrs from it
    for _, attr in self.FIRMWARE_ATTRS:
      setattr(self, attr, None)

    with open(self.firmware_ebuild_path) as f:
      for line in f:
        if '#' in line:
          line, _, _ = line.partition('#')
        line = line.strip()

        for var, attr in self.FIRMWARE_ATTRS:
          if line.startswith('{}='.format(var)):
            _, _, value = line.partition('=')
            value = value.replace('"', '').replace("'", '')
            setattr(self, attr, value)

    # Find make.defaults files
    self.public_make_defaults_file = (
        self.public_overlay / 'profiles' / 'base' / 'make.defaults')
    self.private_make_defaults_file = (
        self.private_overlay / 'profiles' / 'base' / 'make.defaults')

    with open(self.public_make_defaults_file) as f:
      self.public_make_defaults = f.read()
    with open(self.private_make_defaults_file) as f:
      self.private_make_defaults = f.read()

    for var, attr in self.MAKE_DEFAULTS_ATTRS:
      setattr(self, attr, set())
      for script in (self.public_make_defaults, self.private_make_defaults):
        value = sh_getvar(script, var)
        if value:
          for v in value.split():
            getattr(self, attr).add(v)

    if 'whiskers' in self.ec_firmware_extras:
      self.ec_firmware_extras.remove('whiskers')
      self.detachable_base_build_target = 'whiskers'
    else:
      self.detachable_base_build_target = None

    self.ec_build_target = ' '.join(self.ec_firmwares) or None
    self.ec_extras_build_target = sorted(list(self.ec_firmware_extras
                                              | self.pd_firmwares)) or None

  def write_file(self, overlay_flags, path, file_contents):
    dirs = []
    if overlay_flags & M_PUBLIC:
      dirs += [self.public_overlay]
    if overlay_flags & M_PRIVATE:
      dirs += [self.private_overlay]
    for d in dirs:
      write_file(d / path, file_contents)


class Dut:
  def __init__(self, hostname, checkout, port=22):
    self.ssh_hostname = hostname

    id_source = checkout / 'chromite' / 'ssh_keys' / 'testing_rsa'
    with open(id_source, 'rb') as f:
      id_contents = f.read()

    with tempfile.NamedTemporaryFile(mode='wb', delete=False) as tmpfile:
      tmpfile.write(id_contents)
      self.ssh_identity = tmpfile.name

    with tempfile.NamedTemporaryFile(delete=False) as tmpfile:
      self.ssh_known_hosts_file = tmpfile.name

    self.ssh_port = port

    # Check connectivity.
    log('Checking SSH connectivity to DUT...')
    self.run_command(['/bin/true'])

  # Linter is unaware that we set check=True in kwargs.
  # pylint: disable=subprocess-run-check
  def run_command(self, argv, *args, **kwargs):
    kwargs.setdefault('check', True)
    kwargs.setdefault('stdout', subprocess.PIPE)
    kwargs.setdefault('encoding', 'utf-8')
    quoted_argv = [shlex.quote(arg) for arg in argv]
    return subprocess.run(['ssh',
                           '-p', '{}'.format(self.ssh_port),
                           '-i', self.ssh_identity,
                           '-o', 'UserKnownHostsFile={}'.format(
                               self.ssh_known_hosts_file),
                           '-o', 'StrictHostKeyChecking=no',
                           '-o', 'CheckHostIP=no',
                           '-o', 'ConnectTimeout=10',
                           'root@{}'.format(self.ssh_hostname)] + quoted_argv,
                          *args, **kwargs)
  # pylint: enable=subprocess-run-check


class DeviceConfig:
  ATTRS = {
      'brand_code': ['cros_config', '/', 'brand-code'],
      'model': ['cros_config', '/', 'name'],
      'lsb_release': ['cat', '/etc/lsb-release'],
      'smbios_name': ['cat', '/sys/class/dmi/id/product_name'],
      'fdt_compatible_raw': ['cat', '/proc/device-tree/compatible'],
      'arc_build_props': ['cat', '/usr/share/arc/properties/build.prop'],
      'psu_type': ['cros_config', '/hardware-properties', 'psu-type'],
      'whitelabel_tag': ['vpd_get_value', 'whitelabel_tag'],
      'customization_id': ['vpd_get_value', 'customization_id'],
      'vpd_model_name': ['vpd_get_value', 'model_name'],
      'cras_config_dir': ['sh', '/etc/cras/get_device_config_dir'],
      'internal_ucm_suffix': ['sh', '/etc/cras/get_internal_ucm_suffix'],
      # disgusting, but whatever...
      'powerd_raw':
      ['python3', '-c',
       'import os;'
       'import json;'
       'print(json.dumps('
       '{f.replace("_", "-"): open("/usr/share/power_manager/board_specific/"+f).read().rstrip()'
       ' for f in os.listdir("/usr/share/power_manager/board_specific")}))'],
  }

  @classmethod
  def from_dut(cls, dut):
    slf = cls()
    for attr, cmd in cls.ATTRS.items():
      try:
        log('Running {!r} on DUT...'.format(cmd))
        res = dut.run_command(cmd)
      except subprocess.CalledProcessError:
        setattr(slf, attr, None)
      else:
        setattr(slf, attr, res.stdout.strip())
    return slf

  def __str__(self):
    return 'DeviceConfig({})'.format(
        ', '.join('{}={!r}'.format(attr, getattr(self, attr))
                  for attr in self.ATTRS))

  def lsb_val(self, name, default=None):
    for item in self.lsb_release.splitlines():
      k, _, v = item.partition('=')
      if k == name:
        return v
    return default

  def arc_build_prop(self, name, default=None):
    for line in self.arc_build_props.splitlines():
      if '#' in line:
        line, _, _ = line.partition('#')
      line = line.strip()
      if line.startswith('{}='.format(name)):
        _, _, val = line.partition('=')
        return val
    return default

  @property
  def loem(self):
    loem = ''
    if self.customization_id:
      loem, _, _ = self.customization_id.partition('-')
    return loem

  @property
  def chassis(self):
    return self.model.upper()

  @property
  def marketing_name(self):
    return self.vpd_model_name or self.arc_build_prop('ro.product.brand')


def genconf_dt_compatible_match(device, overlay):
  if not device.fdt_compatible_raw:
    return None
  compatible_strings = device.fdt_compatible_raw.strip('\x00').split('\x00')
  compatible_strings.sort(key=lambda s: (s.startswith('google'),
                                         'rev' not in s,
                                         'sku' not in s,
                                         overlay.board_name in s,
                                         -len(s)))
  return compatible_strings[-1]


def genconf_psu_type(device, _):
  if device.psu_type:
    return device.psu_type
  devicetype = device.lsb_val('DEVICETYPE')
  if devicetype == 'CHROMEBOOK':
    return 'battery'
  if devicetype in ('CHROMEBIT', 'CHROMEBASE', 'CHROMEBOX'):
    return 'AC_only'
  return None


def genconf_form_factor(device, _):
  devicetype = device.lsb_val('DEVICETYPE')
  if devicetype in ('REFERENCE', 'CHROMEBOOK'):
    return 'CHROMEBOOK'
  if devicetype in ('CHROMEBIT', 'CHROMEBASE', 'CHROMEBOX'):
    return devicetype
  return None


def genconf_has_backlight(device, _):
  devicetype = device.lsb_val('DEVICETYPE')
  return devicetype not in ('CHROMEBIT', 'CHROMEBOX')


def genconf_fp_board(_, overlay):
  if overlay.fpmcu_firmware:
    return ' '.join(overlay.fpmcu_firmware)
  return None


def genconf_fp_type(_, overlay):
  if 'fp_on_power_button' in overlay.use_flags:
    return 'on-power-button'
  if overlay.fpmcu_firmware:
    return 'stand-alone'
  return None


def genconf_fp_location(_, overlay):
  if overlay.board_name == 'nocturne':
    return 'power-button-top-left'
  return None


def genconf_signature_id(device, _):
  if device.whitelabel_tag:
    return device.whitelabel_tag.upper()
  if device.customization_id:
    return device.customization_id.upper().partition('-')[0]
  return device.model


def genconf_cras_config_dir(device, _):
  prefix = '/etc/cras/'
  if device.cras_config_dir and device.cras_config_dir.startswith(prefix):
    return device.cras_config_dir[len(prefix):]
  if device.cras_config_dir:
    return '../../{}'.format(device.cras_config_dir)
  return None


def genconf_powerd_settings(device, overlay):
  if not device.powerd_raw:
    d = {}
  else:
    d = json.loads(device.powerd_raw)

  # 2-tuples of (use_flag, powerd_option)
  # Source of truth is power_manager ebuild.
  use_flag_settings = [
      ('als', 'has-ambient-light-sensor'),
      ('cras', 'use-cras'),
      ('has_keyboard_backlight', 'has-keyboard-backlight'),
      ('legacy_power_button', 'legacy-power-button'),
      ('mosys_eventlog', 'mosys-eventlog'),
  ]

  for flag, powerd_setting in use_flag_settings:
    if flag in overlay.use_flags:
      d[powerd_setting] = '1'

  return d


def genconf_whitelabel_tag(device, _):
  # Devices with a Customization ID are not compatible with whitelabel
  # tags.
  if device.customization_id:
    return None
  return device.whitelabel_tag or None


def genconf_wallpaper_id(device, overlay):
  wallpapers_dir = (overlay.checkout / 'src' / 'platform' / 'chromeos-assets'
                    / 'wallpaper' / 'large')
  assert wallpapers_dir.is_dir()
  for wallpaper_id in (overlay.board_name, device.model):
    if (wallpapers_dir / f'{wallpaper_id}.jpg').is_file():
      return wallpaper_id
  return None


M_PUBLIC = (1 << 0)
M_PRIVATE = (1 << 1)


genconf_schema = {
    'name': (M_PUBLIC | M_PRIVATE, lambda d, _: d.model),
    'brand-code': (M_PUBLIC, lambda d, _: d.brand_code),
    'arc': {
        'build-properties': {
            'device': (M_PRIVATE, lambda d, _:
                       d.arc_build_prop('ro.product.device')),
            'marketing-name': (M_PRIVATE, lambda d, _: d.marketing_name),
            'oem': (M_PRIVATE,
                    lambda d, _: d.arc_build_prop('ro.product.brand')),
            'metrics-tag': (M_PRIVATE,
                            lambda d, _: d.arc_build_prop('ro.product.board')),
            'product': (M_PRIVATE, lambda d, _:
                        d.arc_build_prop('ro.product.name')),
        },
    },
    'audio': {
        'main': {
            'cras-config-dir': (M_PUBLIC, genconf_cras_config_dir),
            'ucm-suffix': (M_PUBLIC, lambda d, _: d.internal_ucm_suffix),
        },
    },
    'fingerprint': {
        'board': (M_PUBLIC, genconf_fp_board),
        'fingerprint-sensor-type': (M_PUBLIC, genconf_fp_type),
        'sensor-location': (M_PUBLIC, genconf_fp_location),
    },
    'firmware': {
        'image-name': (M_PUBLIC, lambda d, _: d.model),
        'name': (M_PRIVATE, lambda d, _: d.model),
        'bcs-overlay': (M_PRIVATE, lambda _, b:
                        f'overlay-{b.board_name}-private'),
        'ec-ro-image': (M_PRIVATE, lambda _, b: b.bcs_ec),
        'pd-ro-image': (M_PRIVATE, lambda _, b: b.bcs_pd),
        'main-ro-image': (M_PRIVATE, lambda _, b: b.bcs_main_ro),
        'main-rw-image': (M_PRIVATE, lambda _, b: b.bcs_main_rw),
        'build-targets': {
            'base': (M_PUBLIC, lambda _, b: b.detachable_base_build_target),
            'bmpblk': (M_PUBLIC, lambda _, b: b.board_name),
            'coreboot': (M_PUBLIC, lambda _, b: b.board_name),
            'depthcharge': (M_PUBLIC, lambda _, b: b.board_name),
            'ec': (M_PUBLIC, lambda _, b: b.ec_build_target),
            'ec_extras': (M_PUBLIC, lambda _, b: b.ec_extras_build_target),
            'libpayload': (M_PUBLIC, lambda _, b: b.board_name),
        },
    },
    'firmware-signing': {
        'key-id': (M_PRIVATE, lambda d, _: d.model.upper()),
        'signature-id': (M_PRIVATE, genconf_signature_id),
    },
    'hardware-properties': {
        'form-factor': (M_PUBLIC, genconf_form_factor),
        'has-backlight': (M_PUBLIC, genconf_has_backlight),
        'psu-type': (M_PUBLIC, genconf_psu_type),
    },
    'identity': {
        'platform-name': (M_PUBLIC, lambda _, b: b.mosys_platform),
        'smbios-name-match': (M_PUBLIC, lambda d, _: d.smbios_name),
        'device-tree-compatible-match': (M_PUBLIC, genconf_dt_compatible_match),
        'customization-id': (M_PUBLIC, lambda d, _: d.customization_id or None),
        'whitelabel-tag': (M_PUBLIC, genconf_whitelabel_tag),
    },
    'power': (M_PUBLIC, genconf_powerd_settings),
    'wallpaper': (M_PRIVATE, genconf_wallpaper_id),
}


def genconf(schema, device_conf, overlay_conf):

  def qualifies_as_value(v):
    return v is not None and v != {}

  if isinstance(schema, dict):
    pub, priv = {}, {}
    for k, v in schema.items():
      pub_r, priv_r = genconf(v, device_conf, overlay_conf)
      if qualifies_as_value(pub_r):
        pub[k] = pub_r
      if qualifies_as_value(priv_r):
        priv[k] = priv_r
    return pub, priv

  if isinstance(schema, tuple):
    pub, priv = None, None
    flags, func = schema
    value = func(device_conf, overlay_conf)
    if flags & M_PUBLIC:
      pub = value
    if flags & M_PRIVATE:
      priv = value
    return pub, priv


def unify_configs(dev_configs, configs):
  """Merge multiple configs together by replacing device config
  attributes with templates recognized by cros_config_schema (in the
  format {{$device_config_attribute}}).

  Args:
    dev_configs: a list of DeviceConfig to operate on.
    configs: the list of cros_config json-like configs to merge.

  Returns:
    A two tuple of (unified_config, vars_used).
  """
  configs = list(configs)

  def configs_are_unified():
    return all(configs[0] == cfg for cfg in configs[1:])

  if configs_are_unified():
    return configs[0], set()

  if isinstance(configs[0], str):
    replace_vars = ('model', 'loem', 'chassis', 'brand_code', 'smbios_name',
                    'marketing_name')
    vars_used = set()
    for var in replace_vars:
      for i in range(len(configs)):
        device_config = dev_configs[i]
        value = getattr(device_config, var)
        if not value:
          break
        old_config_value = configs[i]
        configs[i] = configs[i].replace(value, '{{$%s}}' % var)
        if i == 0 and configs[i] == old_config_value:
          break
        vars_used.add(var)
      if configs_are_unified():
        return configs[0], vars_used

  if isinstance(configs[0], dict):
    result = {}
    used_vars = set()
    for key in configs[0]:
      item_result, item_used_vars = unify_configs(
          dev_configs, [cfg[key] for cfg in configs]
      )
      result[key] = item_result
      used_vars |= item_used_vars

    return result, used_vars

  raise ValueError("Can't unify configs: {!r}".format(configs))


def validate_gs_uri(uri):
  log('Validating {}...'.format(uri))
  subprocess.run(['gsutil', 'stat', uri], check=True, stdout=subprocess.DEVNULL)


def parse_opts(argv):
  parser = argparse.ArgumentParser()
  parser.add_argument('--cros-checkout',
                      type=pathlib.Path,
                      default=pathlib.Path(os.getenv('HOME')) / 'trunk',
                      help='Location of the ChromeOS checkout')
  parser.add_argument('--dut', '-d',
                      action='append',
                      dest='duts',
                      help=('Hostname of DUT(s) to use for querying. '
                            'Note: multiple duts can be passed, which is useful'
                            ' for converting a zerg board like hana or lars.'))
  parser.add_argument('--board', '-b',
                      type=str,
                      required=True,
                      help='Board name to convert.')
  parser.add_argument('--mosys-platform', type=str, required=True)
  parser.add_argument('--dry-run',
                      action='store_true',
                      default=False,
                      help='Dry run')
  return parser.parse_args(argv)


def main(argv):
  opts = parse_opts(argv)

  overlays = BoardOverlays(opts.board, opts.cros_checkout, opts.mosys_platform)
  duts = []
  for dut_string in opts.duts:
    hostname, _, port = dut_string.partition(':')
    if port:
      port = int(port)
    else:
      port = 22
    duts.append(Dut(hostname, opts.cros_checkout, port=port))

  dut_configs = []
  for dut, dut_string in zip(duts, opts.duts):
    log('Loading configuration from DUT {}...'.format(dut_string))
    dut_config = DeviceConfig.from_dut(dut)
    log('Got configuration: {}'.format(dut_config))

    assert dut_config.lsb_val('CHROMEOS_RELEASE_UNIBUILD', '0') != '1'
    dut_configs.append(dut_config)

  dut_public_configs = []
  dut_private_configs = []
  for dut_config, dut_string in zip(dut_configs, opts.duts):
    log('Generating chromeos-config values for {}...'.format(dut_string))
    dut_public_config, dut_private_config = genconf(
        genconf_schema, dut_config, overlays)
    log("PUBLIC={!r}".format(dut_public_config))
    log("PRIVATE={!r}".format(dut_private_config))
    dut_public_configs.append(dut_public_config)
    dut_private_configs.append(dut_private_config)

  log('Unifying public configs...')
  public_config, public_config_vars = unify_configs(
      dut_configs, dut_public_configs)

  log('Unifying private configs...')
  private_config, private_config_vars = unify_configs(
      dut_configs, dut_private_configs)

  public_config_yaml = format_yaml(
      public_config, dut_configs, public_config_vars
  )
  log('Got public config: \n{}'.format(public_config_yaml))
  private_config_yaml = format_yaml(
      private_config, dut_configs, private_config_vars
  )
  log('Got private config: \n{}'.format(private_config_yaml))

  log('Generating ebuilds...')

  public_bsp_ebuild = generate_bsp_ebuild()
  private_bsp_ebuild = generate_bsp_ebuild(private=True)
  log('Got public bsp_ebuild: \n{}'.format(public_bsp_ebuild))
  log('Got private bsp_ebuild: \n{}'.format(private_bsp_ebuild))

  firmware_ebuild = generate_firmware_ebuild(opts.board)
  log('Got firmware ebuild: \n{}'.format(firmware_ebuild))

  public_make_defaults = generate_make_defaults(overlays.public_make_defaults)
  log('Got public make defaults: \n{}'.format(public_make_defaults))
  private_make_defaults = generate_make_defaults(
      overlays.private_make_defaults,
      private=True,
  )
  log('Got private make defaults: \n{}'.format(private_make_defaults))

  cros_config = CrosConfig(public_config_yaml, private_config_yaml)
  firmware_srcuris = cros_config.run_host_command('get-firmware-uris')
  log('Got firmware URIs: {}'.format(firmware_srcuris))

  log('Validating firmware srcuris...')
  for uri in firmware_srcuris.split():
    validate_gs_uri(uri)

  firmware_srcuris_path = (overlays.firmware_ebuild_path.parent
                           / 'files' / 'srcuris')

  if opts.dry_run:
    return

  overlays.write_file(
      M_PUBLIC, 'chromeos-base/chromeos-config-bsp/files/model.yaml',
      public_config_yaml)
  overlays.write_file(
      M_PRIVATE, 'chromeos-base/chromeos-config-bsp-private/files/model.yaml',
      private_config_yaml)
  overlays.write_file(
      M_PUBLIC,
      'chromeos-base/chromeos-config-bsp/chromeos-config-bsp-9999.ebuild',
      public_bsp_ebuild)
  overlays.write_file(
      M_PRIVATE,
      'chromeos-base/chromeos-config-bsp-private/chromeos-config-bsp-private-9999.ebuild',
      private_bsp_ebuild)
  write_file(overlays.firmware_ebuild_path, firmware_ebuild)
  write_file(firmware_srcuris_path, ''.join('{}\n'.format(uri) for uri in firmware_srcuris.split()))
  write_file(overlays.public_make_defaults_file, public_make_defaults)
  write_file(overlays.private_make_defaults_file, private_make_defaults)


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