#!/usr/bin/env python2
# -*- 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.

"""Mock Omaha server"""

from __future__ import print_function

# pylint: disable=cros-logging-import
import argparse
import base64
import copy
import datetime
import errno
import json
import logging
import os
import shutil
import signal
import sys
import threading
import traceback

from xml.dom import minidom
from xml.etree import ElementTree

from six.moves import BaseHTTPServer
from six.moves import http_client
from six.moves import urllib


# '5' and '7' are just default values for testing.
_FIRMWARE_VER = '5'
_KERNEL_VER = '7'


class Error(Exception):
  """The base class for failures raised by Nebraska."""


class InvalidRequestError(Error):
  """Raised for invalid requests."""


class Request(object):
  """Request consisting of a list of apps to update/install."""

  APP_TAG = 'app'
  APP_APPID_ATTR = 'appid'
  APP_DELTA_OKAY_ATTR = 'delta_okay'
  # The following app attributes should be the same for all incoming apps if
  # they exist. 'version' should be repeated in all apps, but other attributes
  # can be omited in non-platform apps. Or at least they should be present in
  # one of the apps. For this reason we keep these values in the Request
  # object itself and not the AppRequest (except for 'version').
  APP_VERSION_ATTR = 'version'
  APP_CHANNEL_ATTR = 'track'
  APP_BOARD_ATTR = 'board'

  UPDATE_CHECK_TAG = 'updatecheck'
  ROLLBACK_ALLOWED_ATTR = 'rollback_allowed'

  PING_TAG = 'ping'

  EVENT_TAG = 'event'
  EVENT_TYPE_ATTR = 'eventtype'
  EVENT_RESULT_ATTR = 'eventresult'
  EVENT_PREVIOUS_VERSION_ATTR = 'previousversion'

  # Update events and result codes.
  EVENT_TYPE_UNKNOWN = 0
  EVENT_TYPE_DOWNLOAD_COMPLETE = 1
  EVENT_TYPE_INSTALL_COMPLETE = 2
  EVENT_TYPE_UPDATE_COMPLETE = 3
  EVENT_TYPE_UPDATE_DOWNLOAD_STARTED = 13
  EVENT_TYPE_UPDATE_DOWNLOAD_FINISHED = 14

  EVENT_RESULT_ERROR = 0
  EVENT_RESULT_SUCCESS = 1
  EVENT_RESULT_SUCCESS_REBOOT = 2
  EVENT_RESULT_UPDATE_DEFERRED = 9

  class RequestType(object):
    """Simple enumeration for encoding request type."""
    INSTALL = 1 # Request installation of a new app.
    UPDATE = 2 # Request update for an existing app.
    EVENT = 3 # Just an event request.

  def __init__(self, request_str):
    """Initializes a request instance.

    Args:
      request_str: XML-formatted request string.
    """
    self.request_str = request_str
    logging.debug('Received request: %s', self.request_str)

    self.version = None
    self.track = None
    self.board = None
    self.request_type = None
    self.timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    self.app_requests = []

    self.ParseRequest()

  def ParseRequest(self):
    """Parse an XML request string into a list of app requests.

    An app request can be a no-op, an install request, or an update request, and
    may include a ping and/or event tag. We treat app requests with the update
    tag omitted as no-ops, since the server is not required to return payload
    information. Install requests are signalled by sending app requests along
    with a no-op request for the platform app.

    Returns:
      A list of AppRequest instances.

    Raises:
      InvalidRequestError if the request string is not a valid XML request.
    """
    try:
      request_root = ElementTree.fromstring(self.request_str)
    except ElementTree.ParseError as err:
      raise InvalidRequestError(
          'Request string is not valid XML: %s' % err)

    # TODO(http://crbug.com/914936): It would be better to specifically check
    # the platform app. An install is signalled by omitting the update_check for
    # the platform app, so we assume that if we have one appid for which the
    # update_check tag is omitted, it is the platform app and this is an install
    # request. This assumption should be fine since we never mix updates with
    # requests that do not include an update_check tag.
    app_elements = request_root.findall(self.APP_TAG)
    update_check_count = len(
        [x for x in app_elements if x.find(self.UPDATE_CHECK_TAG) is not None])
    if update_check_count == 0:
      self.request_type = Request.RequestType.EVENT
    elif update_check_count == len(app_elements) - 1:
      self.request_type = Request.RequestType.INSTALL
    elif update_check_count == len(app_elements):
      self.request_type = Request.RequestType.UPDATE
    else:
      raise InvalidRequestError(
          'Client request omits update_check tag for more than one, but not all'
          ' app requests.')

    for app in app_elements:
      app_request = Request.AppRequest(app, self.request_type)
      self.app_requests.append(app_request)

    def _CheckAttributesAndReturnIt(attribute, in_all=False):
      """Checks the attribute integrity among all apps and return its value.

      The assumption is that the value of the attribute is the same for all apps
      if existed. It can optionally be in one or more apps, but they are all
      equal.

      Args:
        attribute: An attribute of the app tag.
        in_all: If true, the attribute should exist among all apps.

      Returns:
        The value of the attribute (which is same among all app tags).
      """
      all_attrs = [getattr(x, attribute) for x in self.app_requests]
      if in_all and None in all_attrs:
        raise InvalidRequestError(
            'All apps should have "%s" attribute.' % attribute)

      # Filter out the None elements into a set.
      unique_attrs = set(x for x in all_attrs if x is not None)
      if not unique_attrs:
        raise InvalidRequestError('"%s" attribute should appear in at '
                                  'least one app.' % attribute)
      if len(unique_attrs) > 1:
        raise InvalidRequestError(
            'Attribute "%s" is not the same in all app tags.' % attribute)
      return unique_attrs.pop()

    if self.request_type != Request.RequestType.INSTALL:
      self.version = _CheckAttributesAndReturnIt(self.APP_VERSION_ATTR,
                                                 in_all=True)
    self.track = _CheckAttributesAndReturnIt(self.APP_CHANNEL_ATTR)
    self.board = _CheckAttributesAndReturnIt(self.APP_BOARD_ATTR)

  def GetDict(self):
    """Returns a dictionary with some parameters of the request.

    This is mostly used by the auto update tests to capture the flow of requests
    from update_engine to analyze them (Simply in JSON format).
    """
    if not self.app_requests:
      return {}

    # TODO(ahassani): Extend this to return an object for all App Requests. For
    # now only can return the first one to be backward compatible with auto
    # update auto tests.
    result = self.app_requests[0].__dict__

    # Auto tests require an additional timestamp value which can be considered
    # as a Request wide varable and not App Request one. So set it here.
    result['timestamp'] = self.timestamp

    return result

  class AppRequest(object):
    """An app request.

    Can be an update request, install request, or neither if the update check
    tag is omitted (i.e. the platform app when installing a DLC, or when a
    request is only an event), in which case we treat the request as a no-op.
    An app request can also send pings and event result information.
    """

    def __init__(self, app, request_type):
      """Initializes a Request.

      Args:
        app: The request app XML element.
        request_type: install, update, or event.

        More on event pings:
        https://github.com/google/omaha/blob/master/doc/ServerProtocolV3.md
      """
      self.request_type = request_type
      self.appid = None
      self.version = None
      self.track = None
      self.board = None
      self.ping = None
      self.delta_okay = None
      self.event_type = None
      self.event_result = None
      self.previous_version = None
      self.is_platform = None
      self.rollback_allowed = None

      self.ParseApp(app)

    def __str__(self):
      """Returns a string representation of an AppRequest."""
      if self.request_type == Request.RequestType.EVENT:
        return str(self.appid)
      elif self.request_type == Request.RequestType.INSTALL:
        return 'install %s v%s' % (self.appid, self.version)
      elif self.request_type == Request.RequestType.UPDATE:
        return '%s update %s from v%s' % (
            'delta' if self.delta_okay else 'full', self.appid, self.version)

    def ParseApp(self, app):
      """Parses the app XML element and populates the self object.

      Args:
        app: The request app XML element.

      Raises InvalidRequestError if the input request string is in
          invalid format.
      """
      self.appid = app.get(Request.APP_APPID_ATTR)
      self.version = app.get(Request.APP_VERSION_ATTR)
      self.track = app.get(Request.APP_CHANNEL_ATTR)
      self.board = app.get(Request.APP_BOARD_ATTR)
      self.delta_okay = app.get(Request.APP_DELTA_OKAY_ATTR) == 'true'

      update_check = app.find(Request.UPDATE_CHECK_TAG)
      self.rollback_allowed = (
          update_check is not None and
          update_check.get(Request.ROLLBACK_ALLOWED_ATTR) == 'true')

      event = app.find(Request.EVENT_TAG)
      if event is not None:
        self.event_type = int(event.get(Request.EVENT_TYPE_ATTR))
        self.event_result = int(event.get(Request.EVENT_RESULT_ATTR, 0))
        self.previous_version = event.get(Request.EVENT_PREVIOUS_VERSION_ATTR)

      self.ping = app.find(Request.PING_TAG) is not None

      if None in (self.request_type, self.appid, self.version):
        raise InvalidRequestError('Invalid app request.')

      # This is a weak indication of whether a request is for a platform update
      # (platform App IDs don't have underscore, but DLCs have). But for now it
      # robustly gets what we want.
      self.is_platform = '_' not in self.appid

    def MatchAppData(self, app_data, partial_match_appid=False,
                     check_against_canary=False):
      """Returns true iff the app matches a given client request.

      An app matches a request if the appid matches the requested appid.
      Additionally, if the app describes a delta update payload, the request
      must be able to accept delta payloads.

      Args:
        app_data: An AppData object describing a valid app data.
        partial_match_appid: If true, it will partially check the app_data's
            appid.  Which means that if app_data's appid is a substring of
            request's appid, it will be a match.
        check_against_canary: If the DUT was on a canary channel, the App ID
            update_engine provides is from the canary channel, which is
            different from the release App ID that we use for generating payload
            properties file. But the good news is that there is only one canary
            App ID for all devices. Turning this flag on, checks the incoming
            request against the presumed canary App ID.

      Returns:
        True if the request matches the given app, False otherwise.
      """
      if self.appid != app_data.appid:
        if partial_match_appid:
          if app_data.appid not in self.appid:
            return False
        elif check_against_canary:
          if app_data.canary_appid != self.appid:
            return False
        else:
          return False

      # At this point, there was a match.
      if self.request_type == Request.RequestType.UPDATE:
        if app_data.is_delta:
          return self.delta_okay
        else:
          return True

      if self.request_type == Request.RequestType.INSTALL:
        return not app_data.is_delta

      return False


class Response(object):
  """An update/install response.

  A response to an update or install request consists of an XML-encoded list
  of responses for each appid in the client request. This class takes a list of
  responses for update/install requests and compiles them into a single element
  constituting an aggregate response that can be returned to the client in XML
  format based on the format of an XML response template.
  """

  def __init__(self, request, nebraska_props, response_props):
    """Initialize a reponse from a list of matching apps.

    Args:
      request: Request instance describing client requests.
      nebraska_props: An instance of NebraskaProperties.
      response_props: An instance of ResponseProperties.
    """
    self._request = request
    self._nebraska_props = nebraska_props
    self._response_props = response_props

    curr = datetime.datetime.now()
    # Jan 1 2007 is the start of Omaha v3 epoch:
    # https://github.com/google/omaha/blob/master/doc/ServerProtocolV3.md#attributes-12
    self._elapsed_days = (curr - datetime.datetime(2007, 1, 1)).days
    self._elapsed_seconds = int((
        curr - datetime.datetime.combine(curr.date(),
                                         datetime.time.min)).total_seconds())

  def GetXMLString(self):
    """Generates a response to a set of client requests.

    Given a client request consisting of one or more app requests, generate a
    response to each of these requests and combine them into a single
    XML-formatted response.

    Returns:
      XML-formatted response string consisting of a response to each app request
      in the incoming request from the client.
    """
    try:
      response_xml = ElementTree.Element(
          'response', attrib={'protocol': '3.0', 'server': 'nebraska'})
      ElementTree.SubElement(
          response_xml, 'daystart',
          attrib={'elapsed_days': str(self._elapsed_days),
                  'elapsed_seconds': str(self._elapsed_seconds)})

      for app_request in self._request.app_requests:
        response_xml.append(
            self.AppResponse(app_request, self._nebraska_props,
                             self._response_props).Compile())

    except Exception as err:
      logging.error(traceback.format_exc())
      raise Error('Failed to compile response: %s' % err)

    return ElementTree.tostring(
        response_xml, encoding='UTF-8', method='xml')

  class AppResponse(object):
    """Response to an app request.

    If the request was an update or install request, the response should include
    a matching app if one was found. Addionally, the response should include
    responses to pings and events as appropriate.
    """

    def __init__(self, app_request, nebraska_props, response_props):
      """Initialize an AppResponse.

      Args:
        app_request: AppRequest representing a client request.
        nebraska_props: An instance of NebraskaProperties.
        response_props: An instance of ResponseProperties.
      """
      self._app_request = app_request
      self._response_props = response_props
      self._app_data = None
      self._err_not_found = False
      self._payloads_address = None
      # Although, for installs the update_engine probably should not care about
      # critical updates and should install even if OOBE has not been passed.
      self._critical_update = self._response_props.critical_update

      # If no update was requested, don't process anything anymore.
      if self._response_props.no_update:
        return

      if self._app_request.request_type == Request.RequestType.INSTALL:
        self._app_data = nebraska_props.install_app_index.Find(
            self._app_request)
        self._err_not_found = self._app_data is None
        self._payloads_address = nebraska_props.install_payloads_address
      elif self._app_request.request_type == Request.RequestType.UPDATE:
        self._app_data = nebraska_props.update_app_index.Find(self._app_request)
        self._payloads_address = nebraska_props.update_payloads_address
        # This differentiates between apps that are not in the index and apps
        # that are available, but do not have an update available. Omaha treats
        # the former as an error, whereas the latter case should result in a
        # response containing a "noupdate" tag.
        self._err_not_found = (self._app_data is None and
                               not nebraska_props.update_app_index.Contains(
                                   self._app_request))

      if self._app_data:
        logging.debug('Found matching payload: %s', str(self._app_data))
      elif self._err_not_found:
        logging.debug('No matches for App ID %s', self._app_request.appid)
      elif self._app_request.request_type == Request.RequestType.UPDATE:
        logging.debug('No updates available for App ID %s',
                      self._app_request.appid)

    def Compile(self):
      """Compiles an app description into XML format.

      Compile the app description into an ElementTree Element that can be used
      to compile a response to a client request, and ultimately converted into
      XML.

      Returns:
        An ElementTree Element instance describing an update or install payload.
      """
      app_response = ElementTree.Element(
          'app', attrib={'appid': self._app_request.appid, 'status': 'ok'})

      if self._app_request.ping:
        ElementTree.SubElement(app_response, 'ping', attrib={'status': 'ok'})
      if self._app_request.event_type is not None:
        ElementTree.SubElement(app_response, 'event', attrib={'status': 'ok'})

      if self._app_data is not None:
        update_check_attribs = {'status': 'ok'}
        if (self._response_props.is_rollback and
            self._app_request.rollback_allowed):
          update_check_attribs['_is_rollback'] = 'true'
          # Techincally we have to always send _firmware_version and
          # _kernel_version attributes regardless of the rollback situation. But
          # for the sake of simplicity, we can just send it when rollback was
          # requested.
          index_strs = ['', '_0', '_1', '_2', '_3', '_4']
          for idx in index_strs:
            update_check_attribs['_firmware_version' + idx] = _FIRMWARE_VER
            update_check_attribs['_kernel_version' + idx] = _KERNEL_VER
        if self._response_props.eol_date is not None:
          update_check_attribs['_eol_date'] = str(self._response_props.eol_date)
        update_check = ElementTree.SubElement(
            app_response, 'updatecheck', attrib=update_check_attribs)
        urls = ElementTree.SubElement(update_check, 'urls')
        for _ in range(self._response_props.num_urls):
          ElementTree.SubElement(
              urls, 'url', attrib={'codebase': self._payloads_address})
        manifest = ElementTree.SubElement(
            update_check, 'manifest',
            attrib={'version': self._app_data.target_version})
        actions = ElementTree.SubElement(manifest, 'actions')
        ElementTree.SubElement(
            actions, 'action',
            attrib={'event': 'update', 'run': self._app_data.name})
        action = ElementTree.SubElement(
            actions, 'action',
            attrib={'ChromeOSVersion': self._app_data.target_version,
                    'ChromeVersion': '1.0.0.0',
                    'DisablePayloadBackoff': str(
                        self._response_props.disable_payload_backoff).lower(),
                    'IsDeltaPayload': str(self._app_data.is_delta).lower(),
                    'MaxDaysToScatter': '14',
                    'MetadataSignatureRsa': self._app_data.metadata_signature,
                    'MetadataSize': str(self._app_data.metadata_size),
                    'sha256': self._app_data.sha256,
                    'event': 'postinstall'})
        if self._response_props.failures_per_url is not None:
          action.set('MaxFailureCountPerUrl',
                     str(self._response_props.failures_per_url))
        if self._critical_update:
          action.set('deadline', 'now')
        if self._app_data.public_key is not None:
          action.set('PublicKeyRsa', self._app_data.public_key)
        packages = ElementTree.SubElement(manifest, 'packages')
        ElementTree.SubElement(
            packages, 'package',
            attrib={'fp': '1.%s' % self._app_data.sha256_hex,
                    'hash_sha256': self._app_data.sha256_hex.decode('utf-8'),
                    'name': self._app_data.name,
                    'required': 'true',
                    'size': str(self._app_data.size)})

      elif self._err_not_found and not self._app_request.rollback_allowed:
        app_response.set('status', 'error-unknownApplication')

      elif self._app_request.request_type == Request.RequestType.UPDATE:
        update_check_attribs = {'status': 'noupdate'}
        if self._response_props.eol_date is not None:
          update_check_attribs['_eol_date'] = str(self._response_props.eol_date)
        ElementTree.SubElement(app_response, 'updatecheck',
                               attrib=update_check_attribs)

      return app_response


class AppIndex(object):
  """An index of available app payload information.

  Index of available apps used to generate responses to Omaha requests. The
  index consists of lists of payload information associated with a given appid,
  since we can have multiple payloads for a given app (delta/full payloads). The
  index is built by scanning a given directory for json files that describe the
  available payloads.

  Attributes:
    _directory: Directory containing metdata and payloads, can be None.
    _index: A list of AppData describing payloads.
  """

  def __init__(self, directory):
    """Initializes an AppIndex instance."""
    self._directory = directory
    self._index = []

    self._Scan()

  def _Scan(self):
    """Scans the directory and loads all available properties files."""
    if self._directory is None:
      return

    for f in os.listdir(self._directory):
      if f.endswith('.json'):
        try:
          with open(os.path.join(self._directory, f), 'r') as metafile:
            metadata_str = metafile.read()
            metadata = json.loads(metadata_str)
            # Get the name from file name itself, assuming the metadata file
            # ends with '.json'.
            metadata[AppIndex.AppData.NAME_KEY] = f[:-len('.json')]
            app = AppIndex.AppData(metadata)
            self._index.append(app)
        except (IOError, KeyError, ValueError) as err:
          logging.error('Failed to read app data from %s (%s)', f, str(err))
          raise
        logging.debug('Found app data: %s', str(app))

  def Find(self, request):
    """Search the index for a given appid.

    Searches the index for the payloads matching a client request. Matching is
    based on appid, and whether the client is searching for an update and can
    handle delta payloads.

    Args:
      request: AppRequest describing the client request.

    Returns:
      An AppData object describing an available payload matching the client
      request, or None if no matches are found. Prefer delta payloads if the
      client can accept them and if one is available.
    """
    # Find a list of payloads exactly matching the client request.
    matches = [app_data for app_data in self._index if
               request.MatchAppData(app_data)]

    # Check to see if the incoming requests where from a canary channel (mostly
    # a test image).
    if not matches:
      matches = [app_data for app_data in self._index if
                 request.MatchAppData(app_data, check_against_canary=True)]

    if not matches:
      # Look to see if there is any AppData with empty or partial App ID. Then
      # return the first one you find. This basically will work as a wild card
      # to allow AppDatas that don't have an AppID or their AppID is incomplete
      # (e.g. empty platform App ID + _ + DLC App ID) to work just fine.
      #
      # The reason we just don't do this in one pass is that we want to find all
      # the matches with exact appid and iif there was no match, we do the appid
      # partial match.
      matches = [app_data for app_data in self._index if
                 request.MatchAppData(app_data, partial_match_appid=True)]

    if not matches:
      return None

    # If the client can handle a delta, prefer to send a delta.
    if request.delta_okay:
      match = next((x for x in matches if x.is_delta), None)
      match = match if match else next(iter(matches), None)
    else:
      match = next(iter(matches), None)

    return copy.copy(match)

  def Contains(self, request):
    """Checks if the AppIndex contains any apps matching a given request appid.

    Checks the index for an appid (partially) matching the appid in the given
    request. This is necessary because it allows us to differentiate between the
    case where we have no new versions of an app and the case where we have no
    information about an app at all.

    Args:
      request: Describes the client request.

    Returns:
      True if the index contains any appids matching the appid given in the
      request.
    """
    return any(app_data.appid in request.appid for app_data in self._index)

  class AppData(object):
    """Data about an available app.

    Data about an available app that can be either installed or upgraded
    to. This information is compiled into XML format and returned to the client
    in an app tag in the server's response to an update or install request.

    Attributes:
      appid: App ID of the requested app.
      canary_appid: canary version App ID of the requested app.
      name: Filename of requested app on the mock Lorry server.
      is_delta: True iff the payload is a delta update.
      size: Size of the payload.
      metadata_signature: Metadata signature.
      metadata_size: Metadata size.
      sha256_hex: SHA256 hash of the payload encoded in hexadecimal.
      sha256: SHA256 hash of the payload encoded in base64 format.
      target_version: ChromeOS version the payload is tied to.
      source_version: Source version for delta updates.
      public_key: The public key for signature verification. It should be in
          base64 format.
    """
    APPID_KEY = 'appid'
    NAME_KEY = 'name'
    IS_DELTA_KEY = 'is_delta'
    SIZE_KEY = 'size'
    METADATA_SIG_KEY = 'metadata_signature'
    METADATA_SIZE_KEY = 'metadata_size'
    TARGET_VERSION_KEY = 'target_version'
    SOURCE_VERSION_KEY = 'source_version'
    SHA256_HEX_KEY = 'sha256_hex'
    PUBLIC_KEY_RSA_KEY = 'public_key'

    # This is the same for all images on canary channel.
    CANARY_APP_ID = '{90F229CE-83E2-4FAF-8479-E368A34938B1}'

    def __init__(self, app_data):
      """Initialize AppData.

      Args:
        app_data: Dictionary containing attributes used to initialize AppData
            instance.
      """
      self.appid = app_data[self.APPID_KEY]
      # Replace the begining of the App ID with the canary version.
      self.canary_appid = ''
      if len(self.appid) >= len(self.CANARY_APP_ID):
        self.canary_appid = (self.CANARY_APP_ID +
                             self.appid[len(self.CANARY_APP_ID):])
      self.name = app_data[self.NAME_KEY]
      self.target_version = app_data[self.TARGET_VERSION_KEY]
      self.is_delta = app_data[self.IS_DELTA_KEY]
      self.source_version = (
          app_data[self.SOURCE_VERSION_KEY] if self.is_delta else None)
      self.size = app_data[self.SIZE_KEY]
      # Sometimes the payload is not signed, hence the matadata signature is
      # null, but we should pass empty string instead of letting the value be
      # null (the XML element tree will break).
      self.metadata_signature = app_data[self.METADATA_SIG_KEY] or ''
      self.metadata_size = app_data[self.METADATA_SIZE_KEY]
      self.public_key = app_data.get(self.PUBLIC_KEY_RSA_KEY)
      # Unfortunately the sha256_hex that paygen generates is actually a base64
      # sha256 hash of the payload for some unknown historical reason. But the
      # Omaha response contains the hex value of that hash. So here convert the
      # value from base64 to hex so nebraska can send the correct version to the
      # client. See b/131762584.
      self.sha256 = app_data[self.SHA256_HEX_KEY]
      self.sha256_hex = base64.b16encode(base64.b64decode(self.sha256))
      self.url = None # Determined per-request.

    def __str__(self):
      if self.is_delta:
        return '%s v%s: delta update from base v%s' % (
            self.appid, self.target_version, self.source_version)
      return '%s v%s: full update/install' % (
          self.appid, self.target_version)


class NebraskaProperties(object):
  """An instance of this class contains Nebraska properties.

  These properties are valid and unchanged during the lifetime of the nebraska.
  """

  def __init__(self,
               update_payloads_address=None,
               install_payloads_address=None,
               update_metadata_dir=None,
               install_metadata_dir=None):
    """Initializes the NebraskaProperties instance.

    Args:
      update_payloads_address: Address of the update payload server.
      install_payloads_address: Address of the install payload server. If None
           is passed it will default to update_payloads_address.
      update_metadata_dir: Update payloads metadata directory.
      install_metadata_dir: Install payloads metadata directory.
    """
    # Attach '/' at the end of the addresses if they don't have any. The update
    # engine just concatenates the base address with the payload file name and
    # if there is no '/' the path will be invalid.
    self.update_payloads_address = os.path.join(update_payloads_address or '',
                                                '')
    self.install_payloads_address = (
        os.path.join(install_payloads_address or '', '') or
        self.update_payloads_address)
    self.update_app_index = AppIndex(update_metadata_dir)
    self.install_app_index = AppIndex(install_metadata_dir)


class ResponseProperties(object):
  """An instance of this class contains properties applied for each response.

  These properties might change during the lifetime of the nebraska.
  """
  def __init__(self, **kwargs):
    """Initliazes the response properties.

    Args:
      kwargs: A dictionary of key values to initialize the response
        properties. A list of acceptable values are defined below. Any key other
        than the list below is simply ignored. The reason for this is that
        sometimes the client sends extra values that are only valuable to the
        devserver, but not to Nebraska. That way devserver can just pass through
        the args to Nebraska without picking the valuable ones.

        - critical_update: If true, the response will include 'deadline=now'
          which indicates the update is critical.
        - no_update: If true, it will return a noupdate response regardless.
        - is_rollback: Whether the update request will be a rollback or not.
        - failures_per_url: How many times each url can fail.
        - disable_payload_backoff: Instruct update_engine to disable the
          back-off logic on the client altogether.
        - num_urls: Number of URLs that should be returned in the response.
        - eol_date: The number of days from unix epoch which device goes end of
          life.
    """
    self.critical_update = kwargs.get('critical_update', False)
    self.no_update = kwargs.get('no_update', False)
    self.is_rollback = kwargs.get('is_rollback', False)
    self.failures_per_url = kwargs.get('failures_per_url', None)
    self.disable_payload_backoff = kwargs.get('disable_payload_backoff', False)
    self.num_urls = kwargs.get('num_urls', 1)
    self.eol_date = kwargs.get('eol_date', None)


class Nebraska(object):
  """An instance of this class allows responding to incoming Omaha requests.

    This class has the responsibility to manufacture Omaha responses based on
    the input update requests. This should be the main point of use of the
    Nebraska. If any changes to the behavior of Nebraska is intended, like
    creating critical update responses, or messing up with firmware and kernel
    versions, new flags should be added here to add that feature.
  """
  def __init__(self, nebraska_props=None, response_props=None):
    """Initializes the Nebraska instance.

    Args:
      nebraska_props: An instance of NebraskaProperties.
      response_props: An instance of ResponseProperties.
    """
    self._nebraska_props = nebraska_props or NebraskaProperties()
    self._response_props = response_props or ResponseProperties()
    self._request_log = []

  def GetResponseToRequest(self, request, response_props=None):
    """Returns the response corresponding to a request.

    Args:
      request: The Request object representation of the incoming request.
      response_props: An instance of ResponseProperties. If passed, it will
        override the internal Nebraska version (default).

    Returns:
      The string representation of the created response.
    """
    self._request_log.append(request.GetDict())

    response = Response(request, self._nebraska_props,
                        response_props or self._response_props).GetXMLString()
    # Make the XML response look pretty.
    response_str = minidom.parseString(response).toprettyxml(indent='  ',
                                                             encoding='UTF-8')
    logging.debug('Sent response: %s', response_str)
    return response_str

  def GetRequestLog(self):
    """Returns the request logs in JSON format."""
    return json.dumps(self._request_log).encode('utf-8')


class NebraskaServer(object):
  """A simple Omaha server instance.

  A simple mock of an Omaha server. Responds to XML-formatted update/install
  requests based on the contents of metadata files in update and install
  directories, respectively. These metadata files are used to configure
  responses to Omaha requests from Update Engine and describe update and install
  payloads provided by another server.
  """

  def __init__(self, nebraska, runtime_root=None, port=0):
    """Initializes a server instance.

    Args:
      nebraska: The Nebraska instance to process requests and responses.
      runtime_root: The root directory in which nebraska will write its PID and
        port files.
      port: Port the server should run on, 0 if the OS should assign a port.
    """
    self.nebraska = nebraska
    self._runtime_root = runtime_root
    self._port = port

    if self._runtime_root:
      self._port_file = os.path.join(self._runtime_root, 'port')
      self._pid_file = os.path.join(self._runtime_root, 'pid')

    self._httpd = None
    self._server_thread = None
    self._created_runtime_root = False

  class NebraskaHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    """HTTP request handler for Omaha requests."""

    def _SendResponse(self, content_type, response, code=http_client.OK):
      """Sends a given response back to the client.

      Args:
        content_type: The content type of the response data: xml, json, etc.
        response: The response content in string format.
        code: The HTTP code to send back to the client.
      """
      self.send_response(code)
      self.send_header('Content-Type', content_type)
      self.end_headers()
      self.wfile.write(response)

    def _ParseURL(self, url):
      """Parses a URL into usable components.

      Args:
        url: The input URL to parse.

      Returns:
        A tuple of parsed path and parsed query. The parsed query is a
        dictionary of keys to list of values. e.g:
        - http://goo.gle/path/?key=value1&key=value2 ->
          ('path', {'key': ['value1', 'value2']})
      """
      parsed_result = urllib.parse.urlparse(url)
      parsed_path = parsed_result.path.strip('/')
      parsed_query = urllib.parse.parse_qs(parsed_result.query)
      return parsed_path, parsed_query

    def do_POST(self):
      """Responds to XML-formatted Omaha requests.

      The URL path can be like:
          https://<ip>:<port>/update/?key1=value1&key2=value2...

      Look at ResponseProperties for a list of available attributes.
      """
      try:
        request_len = int(self.headers.get('content-length'))
        request = self.rfile.read(request_len)
      except Exception as err:
        logging.error('Failed to read request in do_POST %s', str(err))
        self.send_error(http_client.BAD_REQUEST, 'Invalid request (header).')
        return

      parsed_path, parsed_query = self._ParseURL(self.path)
      if parsed_path == 'update':
        true_lambda = lambda a: a == 'True'
        kwargs = {}
        for k, t in {'critical_update': true_lambda,
                     'disable_payload_backoff':  true_lambda,
                     'eol_date': int,
                     'failures_per_url': int,
                     'no_update': true_lambda,
                     'num_urls': int}.items():
          value = parsed_query.get(k)
          if value:
            kwargs[k] = t(value[0])

        response_props = ResponseProperties(**kwargs)

        try:
          request_obj = Request(request)
          response = self.server.owner.nebraska.GetResponseToRequest(
              request_obj, response_props)
          self._SendResponse('application/xml', response)
        except Exception as err:
          logging.error('Failed to handle request (%s)', str(err))
          logging.error(traceback.format_exc())
          self.send_error(http_client.INTERNAL_SERVER_ERROR,
                          traceback.format_exc())

      else:
        logging.error('The requested path "%s" was not found!', parsed_path)
        self.send_error(http_client.BAD_REQUEST,
                        'The requested path "%s" was not found!' % parsed_path)

    def do_GET(self):
      """Responds to Get requests.

      The use cases are:
      - requestlog: For getting the list of request logs in a JSON format.

      The URL path can be like:
          https://<ip>:<port>/requestlog
      """
      parsed_path, _ = self._ParseURL(self.path)

      if parsed_path == 'requestlog':
        try:
          response = self.server.owner.nebraska.GetRequestLog()
          self._SendResponse('application/json', response)
        except Exception as err:
          logging.error('Failed to get request logs (%s)', str(err))
          logging.error(traceback.format_exc())
          self.send_error(http_client.INTERNAL_SERVER_ERROR,
                          traceback.format_exc())
      elif parsed_path == 'health_check':
        self._SendResponse('text/plain', 'Nebraska is alive!')
      else:
        logging.error('The requested path "%s" was not found!', parsed_path)
        self.send_error(http_client.BAD_REQUEST,
                        'The requested path "%s" was not found!' % parsed_path)

  def Start(self):
    """Starts the nebraska server."""
    self._httpd = BaseHTTPServer.HTTPServer(('', self.GetPort()),
                                            NebraskaServer.NebraskaHandler)
    self._port = self._httpd.server_port

    if self._runtime_root:
      try:
        if not os.path.exists(self._runtime_root):
          os.makedirs(self._runtime_root)
          self._created_runtime_root = True
        with open(self._port_file, 'w') as port_file:
          port_file.write(str(self._port))
        with open(self._pid_file, 'w') as pid_file:
          pid_file.write(str(os.getpid()))
      except IOError as err:
        if err.errno == errno.EACCES:
          print('Permission error: You need to run the script as root/sudo or '
                'change the --runtime-root to point to a non-root accessible '
                'location.')
        raise

    self._httpd.owner = self
    self._server_thread = threading.Thread(target=self._httpd.serve_forever)
    self._server_thread.start()

    logging.info('Started nebraska on port %d and pid %d.',
                 self._port, os.getpid())

  def Stop(self):
    """Stops the mock Omaha server."""
    self._httpd.shutdown()
    self._server_thread.join()

    if not self._runtime_root:
      return
    for f in {self._port_file, self._pid_file}:
      try:
        os.remove(f)
      except Exception as e:
        logging.warning('Failed to remove file %s with error %s', f, e)
    if self._created_runtime_root:
      try:
        shutil.rmtree(self._runtime_root)
      except Exception as e:
        logging.warning('Failed to remove directory %s with error %s',
                        self._runtime_root, e)


  def GetPort(self):
    """Returns the server's port."""
    return self._port


def ParseArguments(argv):
  """Parses command line arguments.

  Args:
    argv: List of commandline arguments.

  Returns:
    Namespace object containing parsed arguments.
  """
  parser = argparse.ArgumentParser(
      description=__doc__,
      formatter_class=argparse.ArgumentDefaultsHelpFormatter)

  parser.add_argument('--update-metadata', metavar='DIR', default=None,
                      help='Payloads metadata directory for update.')
  parser.add_argument('--install-metadata', metavar='DIR', default=None,
                      help='Payloads metadata directory for install.')
  parser.add_argument('--update-payloads-address', metavar='URL',
                      help='Base payload URI for update payloads',
                      default='http://127.0.0.1:8080')
  parser.add_argument('--install-payloads-address', metavar='URL',
                      help='Base payload URI for install payloads. If not '
                      'passed it will default to --update-payloads-address')

  parser.add_argument('--port', metavar='PORT', type=int, default=0,
                      help='Port to run the server on.')
  parser.add_argument('--runtime-root', metavar='DIR',
                      default='/run/nebraska',
                      help='The root directory in which nebraska will write its'
                      ' pid and port files.')
  parser.add_argument('--log-file', metavar='FILE', default='/tmp/nebraska.log',
                      help='The file to write the logs.'
                      ' pass "stdout" to write to standard output.')

  return parser.parse_args(argv[1:])


def main(argv):
  """Main function."""
  opts = ParseArguments(argv)

  # Reset the log file.
  if opts.log_file != 'stdout':
    with open(opts.log_file, 'w') as _:
      pass
    print('Logging to %s' % opts.log_file)

  logging.basicConfig(filename=(opts.log_file if opts.log_file != 'stdout'
                                else None),
                      level=logging.DEBUG)

  logging.info('Starting nebraska ...')

  nebraska_props = NebraskaProperties(
      update_payloads_address=opts.update_payloads_address,
      install_payloads_address=opts.install_payloads_address,
      update_metadata_dir=opts.update_metadata,
      install_metadata_dir=opts.install_metadata)
  nebraska = Nebraska(nebraska_props)
  nebraska_server = NebraskaServer(nebraska, runtime_root=opts.runtime_root,
                                   port=opts.port)

  def handler(signum, _):
    logging.info('Exiting Nebraska with signal %d ...', signum)
    nebraska_server.Stop()

  signal.signal(signal.SIGINT, handler)
  signal.signal(signal.SIGTERM, handler)

  nebraska_server.Start()

  signal.pause()

  return os.EX_OK


if __name__ == '__main__':
  sys.exit(main(sys.argv))
