# -*- coding: utf-8 -*-
# Copyright 2018 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.

"""Provision a recovery image for OOBE autoconfiguration.

This script populates the OOBE autoconfiguration data
(/stateful/unencrypted/oobe_auto_config/config.json) with the given parameters.

Additionally, it marks the image as being "hands-free", i.e. requiring no
physical user interaction to remove the recovery media before rebooting after
the recovery procedure has completed.

Any parameters prefixed with --x (e.g. --x-demo-mode) correspond directly to
generated elements in the configuration expected by OOBE.
"""

from __future__ import print_function

import json
import os
import sys
import uuid

from chromite.lib import commandline
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import image_lib
from chromite.lib import osutils


assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'


# OOBE auto-config parameters as they appear in
#   chrome/browser/chromeos/login/configuration_keys.h
# Please keep the keys grouped in the same order as the source file.
_CONFIG_PARAMETERS = (
    ('demo-mode', bool, 'Whether the device should be placed into demo mode.'),
    ('network-onc', str, 'ONC blob for network configuration.'),
    ('network-auto-connect', bool,
     'Whether the network screen should automatically proceed with '
     'connected network.'),
    ('eula-send-statistics', bool,
     'Whether the device should send usage statistics.'),
    ('eula-auto-accept', bool,
     'Whether the EULA should be automatically accepted.'),
    ('update-skip', bool,
     'Whether the udpate check should be skipped entirely (it may be '
     'required for future version pinning).'),
    ('wizard-auto-enroll', bool,
     'Whether the wizard should automatically start enrollment at the '
     'appropriate moment.'),
)

# Set of flags to specify when building with --generic.
_GENERIC_FLAGS = {
    'network-auto-connect': True,
    'eula-send-statistics': True,
    'eula-auto-accept': True,
    'update-skip': True,
}

# Mapping of flag type to argparse kwargs.
_ARG_TYPES = {
    str: {},
    bool: {'action': 'store_true'},
}

# Name of the OOBE directory in unencrypted/.
_OOBE_DIRECTORY = 'oobe_auto_config'

# Name of the configuration file in the recovery image.
_CONFIG_PATH = 'config.json'

# Name of the file containing the enrollment domain.
_DOMAIN_PATH = 'enrollment_domain'


def SanitizeDomain(domain):
  """Sanitized |domain| for use in recovery.

  Args:
    domain: (str) The original string.

  Returns:
    (str) The sanitized domain name, possibly using punycode to disambiguate.
  """
  # Encode using punycode ("idna" here) to prevent homograph attacks.
  # Once that's been normalized to ASCII, normalize to lowercase.
  return domain.encode('idna').decode('utf-8').lower()


def GetConfigContent(opts):
  """Formats OOBE autoconfiguration from commandline namespace.

  Args:
    opts: A commandline namespace containing OOBE autoconfig opts.

  Returns:
    A JSON string representation of the requested configuration.
  """
  conf = {}

  for flag, _, _ in _CONFIG_PARAMETERS:
    conf[flag] = getattr(opts, 'x_' + flag.replace('-', '_'))

  if opts.wifi_ssid:
    conf['network-onc'] = {
        'GUID': str(uuid.uuid4()),
        'Name': opts.wifi_ssid,
        'Type': 'WiFi',
        'WiFi': {
            'AutoConnect': True,
            'HiddenSSID': False,
            'SSID': opts.wifi_ssid,
            'Security': 'None',
        },
    }

  if opts.use_ethernet:
    conf['network-onc'] = {
        'GUID': str(uuid.uuid4()),
        'Name': 'Ethernet',
        'Type': 'Ethernet',
        'Ethernet': {
            'Authentication': 'None',
        },
    }

  return json.dumps(conf)


def PrepareImage(path, content, domain=None):
  """Prepares a recovery image for OOBE autoconfiguration.

  Args:
    path: Path to the recovery image.
    content: The content of the OOBE autoconfiguration.
    domain: Which domain to enroll to.
  """
  with osutils.TempDir() as tmp, \
    image_lib.LoopbackPartitions(path, tmp) as image:
    stateful_mnt = image.Mount((constants.CROS_PART_STATEFUL,),
                               mount_opts=('rw',))[0]

    # /stateful/unencrypted may not exist at this point in time on the
    # recovery image, so create it root-owned here.
    unencrypted = os.path.join(stateful_mnt, 'unencrypted')
    osutils.SafeMakedirs(unencrypted, mode=0o755, sudo=True)

    # The OOBE autoconfig directory must be owned by the chronos user so
    # that we can delete the config file from it from Chrome.
    oobe_autoconf = os.path.join(unencrypted, _OOBE_DIRECTORY)
    osutils.SafeMakedirsNonRoot(oobe_autoconf, user='chronos')

    # Create the config file to be owned by the chronos user, and write the
    # given data into it.
    config = os.path.join(oobe_autoconf, _CONFIG_PATH)
    osutils.WriteFile(config, content, sudo=True)
    cros_build_lib.sudo_run(['chown', 'chronos:chronos', config])

    # If we have a plaintext domain name, write it.
    if domain:
      domain_path = os.path.join(oobe_autoconf, _DOMAIN_PATH)
      osutils.WriteFile(domain_path, SanitizeDomain(domain), sudo=True)
      cros_build_lib.sudo_run(['chown', 'chronos:chronos', domain_path])


def ParseArguments(argv):
  """Returns a namespace for the CLI arguments."""
  parser = commandline.ArgumentParser(description=__doc__)
  parser.add_argument('image', help='Path of recovery image to populate.')

  # Prefix raw config elements with --x.
  for flag, flag_type, help_text in _CONFIG_PARAMETERS:
    parser.add_argument('--x-%s' % flag, help=help_text,
                        **_ARG_TYPES[flag_type])

  parser.add_argument('--generic', action='store_true',
                      help='Set defaults for common configuration options.')
  parser.add_argument('--dump-config', action='store_true',
                      help='Dump generated configuration file to stdout.')
  parser.add_argument('--config', type='path', required=False,
                      help='Path to pre-generated configuration file to use, '
                           'overriding other flags set.')
  parser.add_argument('--wifi-ssid', type=str, required=False,
                      help='If specified, generates an ONC for auto-connecting '
                           'to the given SSID. The network must not use any '
                           'security (i.e. be an open network), or the device '
                           'will fail to connect.')
  parser.add_argument('--use-ethernet', action='store_true',
                      help='If specified, generates an ONC for auto-connecting '
                           'via ethernet.')
  parser.add_argument('--enrollment-domain', type=str, required=False,
                      help='Text to visually identify the enrollment token in '
                           'recovery.')

  opts = parser.parse_args(argv)

  if opts.use_ethernet and opts.wifi_ssid:
    parser.error('cannot specify --wifi-ssid and --use-ethernet together')

  if opts.generic:
    for opt, val in _GENERIC_FLAGS.items():
      setattr(opts, 'x_' + opt.replace('-', '_'), val)

  opts.Freeze()
  return opts


def main(argv):
  cros_build_lib.AssertInsideChroot()

  opts = ParseArguments(argv)

  if opts.config:
    config_content = osutils.ReadFile(opts.config)
  else:
    config_content = GetConfigContent(opts)

  logging.info('Using config: %s', config_content)

  if opts.dump_config:
    print(config_content)

  PrepareImage(opts.image, config_content, opts.enrollment_domain)
