#!/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 coverned 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):
  conf_str = yaml.dump(config, indent=2, default_flow_style=False)
  out = gen_cros_copyright()
  out += """
# This board only supports a single config, defined below, as it is a
# migrated pre-unibuild device.
device-config: &device_config\n"""
  out += prepend_all_lines(conf_str, '  ')
  out += """
# Required dunder for chromeos-config to support a single device.
chromeos:
  devices:
    - skus:
        - config: *device_config\n"""
  return out


def generate_vpackage(depends):
  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

DESCRIPTION="ChromeOS Unibuild Config virtual package"
HOMEPAGE="https://chromium.googlesource.com/chromiumos/platform2/+/master/chromeos-config/README.md"

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

DEPEND="%(depends)s"
RDEPEND="${DEPEND}"
""" % {
    'depends':
    (''.join('\n\t{}'.format(d) for d in depends) + '\n')
    if len(depends) > 1 else
    ''.join(depends)}


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"
CROS_BOARDS=( %(board_name)s )

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):
  contents = make_defaults_search_and_destroy_re.sub('', contents)
  contents += """
# Enable chromeos-config.
USE="${USE} unibuild"
"""
  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.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': ['mosys', 'platform', 'brand'],
      'model': ['mosys', 'platform', 'model'],
      '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'],
      'mosys_psu_type': ['mosys', 'psu', 'type'],
      'whitelabel_tag': ['vpd_get_value', 'whitelabel_tag'],
      'customization_id': ['vpd_get_value', 'customization_id'],
      '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


def genconf_first_api_level(_, overlay):
  if overlay.board_name in ('atlas', 'nocturne'):
    return '28'
  return '25'


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.mosys_psu_type:
    return device.mosys_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_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)
  if 'mosys_eventlog' in overlay.use_flags:
    d['mosys-eventlog'] = '1'
  return d


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.arc_build_prop('ro.product.model')),
            'oem': (M_PRIVATE,
                    lambda d, _: d.arc_build_prop('ro.product.brand')),
            'first-api-level': (M_PRIVATE, genconf_first_api_level),
            '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),
            '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),
        },
    },
    'firmware-signing': {
        'key-id': (M_PRIVATE, lambda d, _: d.model.upper()),
        'signature-id': (M_PRIVATE, genconf_signature_id),
    },
    'hardware-properties': {
        'psu-type': (M_PUBLIC, genconf_psu_type),
    },
    'identity': {
        'platform-name': (M_PUBLIC, lambda _, b: b.mosys_platform),
        'smbios-name-match': (M_PUBLIC | M_PRIVATE, lambda d, _: d.smbios_name),
        'device-tree-compatible-match': (M_PUBLIC | M_PRIVATE,
                                         genconf_dt_compatible_match),
    },
    'power': (M_PUBLIC, genconf_powerd_settings),
}


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 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',
                      type=str,
                      required=True,
                      help='Hostname of DUT to use for querying and testing.')
  parser.add_argument('--dut-ssh-port', type=int, default=22,
                      help='SSH port to use on the dut.')
  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)
  dut = Dut(opts.dut, opts.cros_checkout, port=opts.dut_ssh_port)

  log('Loading configuration from DUT...')
  dut_config = DeviceConfig.from_dut(dut)
  log('Got configuration: {}'.format(dut_config))

  assert dut_config.lsb_val('CHROMEOS_RELEASE_BOARD') == opts.board
  assert dut_config.lsb_val('CHROMEOS_RELEASE_UNIBUILD', '0') != '1'

  log('Generating chromeos-config values...')
  public_config, private_config = genconf(genconf_schema, dut_config, overlays)

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

  log('Generating ebuilds...')

  public_vpackage = generate_vpackage(('chromeos-base/chromeos-config-bsp', ))
  private_vpackage = generate_vpackage(
      ('chromeos-base/chromeos-config-bsp',
       'chromeos-base/chromeos-config-bsp-private'))
  log('Got public vpackage: \n{}'.format(public_vpackage))
  log('Got private vpackage: \n{}'.format(private_vpackage))

  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)
  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, 'virtual/chromeos-config-bsp/chromeos-config-bsp-9999.ebuild',
      public_vpackage)
  overlays.write_file(
      M_PRIVATE, 'virtual/chromeos-config-bsp/chromeos-config-bsp-9999.ebuild',
      private_vpackage)
  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, firmware_srcuris)
  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:])
