#!/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'),
  ]

  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:])
