#!/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 errno
import httplib
import json
import logging
import os
import shutil
import signal
import sys
import threading
import traceback
import urlparse

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from datetime import datetime, time
from xml.dom import minidom
from xml.etree import ElementTree


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


class NebraskaErrorInvalidRequest(NebraskaError):
  """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'

  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.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:
      NebrakaErrorInvalidRequest if the request string is not a valid XML
          request.
    """
    try:
      request_root = ElementTree.fromstring(self.request_str)
    except ElementTree.ParseError as err:
      raise NebraskaErrorInvalidRequest(
          'Request string is not valid XML: {}'.format(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 NebraskaErrorInvalidRequest(
          '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 NebraskaErrorInvalidRequest(
            'All apps should have "{}" attribute.'.format(attribute))

      # Filter out the None elements into a set.
      unique_attrs = set(filter(None, all_attrs))
      if len(unique_attrs) == 0:
        raise NebraskaErrorInvalidRequest('"{}" attribute should appear in at '
                                          'least one app.'.format(attribute))
      if len(unique_attrs) > 1:
        raise NebraskaErrorInvalidRequest(
            'Attribute "{}" is not the same in all app tags.'.format(attribute))
      return unique_attrs.pop()

    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.ParseApp(app)

    def __str__(self):
      """Returns a string representation of an AppRequest."""
      if self.request_type == Request.RequestType.EVENT:
        return '{}'.format(self.appid)
      elif self.request_type == Request.RequestType.INSTALL:
        return 'install {} v{}'.format(self.appid, self.version)
      elif self.request_type == Request.RequestType.UPDATE:
        return '{} update {} from v{}'.format(
            '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 NebraskaErrorInvalidRequest 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'

      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 NebraskaErrorInvalidRequest('Invalid app request.')

    def MatchAppData(self, app_data, partial_match_appid=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.

      Returns:
        True if the request matches the given app, False otherwise.
      """
      if self.appid != app_data.appid:
        if not partial_match_appid or (app_data.appid is not None and
                                       app_data.appid not in self.appid):
          return False

      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, properties):
    """Initialize a reponse from a list of matching apps.

    Args:
      request: Request instance describing client requests.
      properties: An instance of NebraskaProperties.
    """
    self._request = request
    self._properties = properties

    curr = datetime.now()
    self._elapsed_days = (curr - datetime(2007, 1, 1)).days
    self._elapsed_seconds = int((
        curr - datetime.combine(curr.date(), 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._properties).Compile())

    except Exception as err:
      logging.error(traceback.format_exc())
      raise NebraskaError('Failed to compile response: {}'.format(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, properties):
      """Initialize an AppResponse.

      Attributes:
        app_request: AppRequest representing a client request.
        properties: An instance of NebraskaProperties.
      """
      self._app_request = app_request
      self._app_data = None
      self._err_not_found = False
      self._payloads_address = None
      self._critical_update = False

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

      if self._app_request.request_type == Request.RequestType.INSTALL:
        self._app_data = properties.install_app_index.Find(self._app_request)
        self._err_not_found = self._app_data is None
        self._payloads_address = properties.install_payloads_address
      elif self._app_request.request_type == Request.RequestType.UPDATE:
        self._app_data = properties.update_app_index.Find(self._app_request)
        self._payloads_address = properties.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 properties.update_app_index.Contains(
                                   self._app_request))
        self._critical_update = properties.critical_update

      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 = ElementTree.SubElement(
            app_response, 'updatecheck', attrib={'status': 'ok'})
        urls = ElementTree.SubElement(update_check, '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',
                    'IsDeltaPayload': str(self._app_data.is_delta).lower(),
                    'MaxDaysToScatter': '14',
                    'MetadataSignatureRsa': self._app_data.metadata_signature,
                    'MetadataSize': str(self._app_data.metadata_size),
                    'event': 'postinstall'})
        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,
                    'name': self._app_data.name,
                    'required': 'true',
                    'size': str(self._app_data.size)})

      elif self._err_not_found:
        app_response.set('status', 'error-unknownApplication')

      elif self._app_request.request_type == Request.RequestType.UPDATE:
        ElementTree.SubElement(app_response, 'updatecheck',
                               attrib={'status': 'noupdate'})

      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.
  """

  def __init__(self, directory):
    """Initializes an AppIndex instance.

    Attributes:
      directory: Directory containing metdata and payloads, can be None.
      index: A list of AppData describing payloads.
    """
    self._directory = directory
    self._index = []

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

    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.
    """

    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'

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

      Args:
        app_data: Dictionary containing attributes used to initialize AppData
            instance.

      Attributes:
        template: Defines the format of an app element in the XML response.
        appid: appid 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.
        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.
      """
      self.appid = app_data[self.APPID_KEY]
      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_hex = base64.b64decode(
          app_data[self.SHA256_HEX_KEY]).encode('hex')
      self.url = None # Determined per-request.

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


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

  def __init__(self, update_payloads_address, install_payloads_address,
               update_app_index, install_app_index):
    """Initializes the NebraskaProperties instance.

    Args:
      update_payloads_address: Address serving update payloads.
      install_payloads_address: Address serving install payloads.
      update_app_index: Index of update payloads.
      install_app_index: Index of install payloads.
    """
    self.update_payloads_address = update_payloads_address
    self.install_payloads_address = install_payloads_address
    self.update_app_index = update_app_index
    self.install_app_index = install_app_index
    self.critical_update = False
    self.no_update = False


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,
               update_payloads_address=None,
               install_payloads_address=None,
               update_metadata_dir=None,
               install_metadata_dir=None):
    """Initializes the Nebraska 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.
    upa = os.path.join(update_payloads_address or '', '')
    ipa = (os.path.join(install_payloads_address, '')
           if install_payloads_address is not None else upa)
    uai = AppIndex(update_metadata_dir)
    iai = AppIndex(install_metadata_dir)
    uai.Scan()
    iai.Scan()

    self._properties = NebraskaProperties(upa, ipa, uai, iai)

    self._request_log = []

  def GetResponseToRequest(self, request, critical_update=False,
                           no_update=False):
    """Returns the response corresponding to a request.

    Args:
      request: The Request object representation of the incoming request.
      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.

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

    properties = copy.copy(self._properties)
    properties.critical_update = critical_update
    properties.no_update = no_update
    response = Response(request, properties).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)

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(BaseHTTPRequestHandler):
    """HTTP request handler for Omaha requests."""

    def _SendResponse(self, content_type, response, code=httplib.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 = urlparse.urlparse(url)
      parsed_path = parsed_result.path.strip('/')
      parsed_query = urlparse.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...

      The keys in query strings can be:
      - critical_update: (boolean) For requesting a critical update response.
      - no_update: (boolean) For requesting a response that indicates there is
          no update (even if there is).
      """
      try:
        request_len = int(self.headers.getheader('content-length'))
        request = self.rfile.read(request_len)
      except Exception as err:
        self.send_error(httplib.BAD_REQUEST, 'Invalid request (header).')
        return

      parsed_path, parsed_query = self._ParseURL(self.path)

      if parsed_path == 'update':
        critical_update = parsed_query.get('critical_update', []) == ['True']
        no_update = parsed_query.get('no_update', []) == ['True']

        try:
          request_obj = Request(request)
          response = self.server.owner.nebraska.GetResponseToRequest(
              request_obj, critical_update=critical_update, no_update=no_update)
          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(httplib.INTERNAL_SERVER_ERROR, traceback.format_exc())

      else:
        logging.error('The requested path "%s" was not found!', parsed_path)
        self.send_error(httplib.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(httplib.INTERNAL_SERVER_ERROR, traceback.format_exc())
      else:
        logging.error('The requested path "%s" was not found!', parsed_path)
        self.send_error(httplib.BAD_REQUEST,
                        'The requested path "%s" was not found!' % parsed_path)

  def Start(self):
    """Starts the nebraska server."""
    self._httpd = 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.warn('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.warn('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 = Nebraska(
      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_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))
