#!/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 copy
import json
import logging
import os
import sys
import threading
import traceback

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


class XMLResponseTemplates(object):
  """XML Templates"""

  RESPONSE_TEMPLATE = """<?xml version="1.0" encoding="UTF-8"?>
<response protocol="3.0" server="nebraska">
  <daystart elapsed_days="" elapsed_seconds=""/>
</response>
"""

  APP_TEMPLATE = """
  <app appid="" status="">
  </app>
"""

  PING_RESPONSE = """
    <ping status="ok"/>
  """

  EVENT_RESPONSE = """
    <event status="ok"/>
  """

  UPDATE_CHECK_TEMPLATE = """
    <updatecheck status="ok">
      <urls>
      </urls>
      <manifest version="">
        <actions>
          <action event="update" run=""/>
          <action ChromeOSVersion=""
                  ChromeVersion="1.0.0.0"
                  IsDeltaPayload=""
                  MaxDaysToScatter="14"
                  MetadataSignatureRsa=""
                  MetadataSize=""
                  event="postinstall"/>
        </actions>
        <packages>
          <package fp=""
                   hash_sha256=""
                   name=""
                   required="true"
                   size=""/>
        </packages>
      </manifest>
    </updatecheck>
  """

  UPDATE_CHECK_NO_UPDATE = """
    <updatecheck status="noupdate"/>
  """

  ERROR_NOT_FOUND = "error-unknownApplication"


def VersionCmp(version_a_str, version_b_str):
  """Compare two version strings.

  Currently we only match on major/minor versions.

  Args:
    version_a_str: String representing first version number.
    version_b_str: String representing second version number.

  Returns:
    < 0 if version_a is less than version_b.
    > 0 if version_a is greater than version_b.
    0 if the version numbers are equal.

  Raises:
    ValueError if either version string is not valid.
  """

  try:
    version_a = tuple([int(i) for i in version_a_str.split('.')[0:2]])
    version_b = tuple([int(i) for i in version_b_str.split('.')[0:2]])

    if version_a[0] != version_b[0]:
      return version_a[0] - version_b[0]

    return version_a[1] - version_b[1]

  except (IndexError, ValueError):
    raise ValueError("Not a valid version string")


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

  APP_TAG = 'app'
  APPID_ATTR = 'appid'
  VERSION_ATTR = 'version'
  DELTA_OKAY_ATTR = 'delta_okay'
  HW_CLASS_ATTR = 'hardware_class'
  UPDATE_CHECK_TAG = 'updatecheck'
  PING_TAG = 'ping'
  EVENT_TAG = 'event'
  EVENT_TYPE_ATTR = 'eventtype'
  EVENT_RESULT_ATTR = 'eventresult'

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

    Args:
      request_str: XML-formatted request string.
    """
    self.request_str = request_str

  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:
      ValueError if the request string is not a valid XML request.
    """
    try:
      request_root = ElementTree.fromstring(self.request_str)
    except ElementTree.ParseError as err:
      logging.error("Request string is not valid XML (%s)", str(err))
      raise ValueError

    # TODO(chowes): It would be better to specifically check the platform app.
    # An install is signalled by omitting the update check for the platform
    # app, which can be found based on the presense of a hardware_class tag,
    # which is absent on DLC update and install requests. UE does not currently
    # omit hardware_class for DLCs, 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)
    noop_count = len(
        [x for x in app_elements if x.find(self.UPDATE_CHECK_TAG) is None])

    if noop_count > 1 and noop_count < len(app_elements):
      raise ValueError("Client request omits update_check tag for more than "
                       "one, but not all app requests.")

    is_install = noop_count == 1

    app_requests = []
    for app in app_elements:
      appid = app.get(self.APPID_ATTR)
      version = app.get(self.VERSION_ATTR)
      delta_okay = app.get(self.DELTA_OKAY_ATTR) == "true"

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

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

      if app.find(self.UPDATE_CHECK_TAG) is not None:
        if is_install:
          request_type = Request.AppRequest.RequestType.INSTALL
        else:
          request_type = Request.AppRequest.RequestType.UPDATE
      else:
        request_type = Request.AppRequest.RequestType.NO_OP

      app_request = Request.AppRequest(
          request_type=request_type,
          appid=appid,
          ping=ping,
          version=version,
          delta_okay=delta_okay,
          event_type=event_type,
          event_result=event_result)

      if not app_request.IsValid():
        raise ValueError("Invalid request: %s", str(app_request))

      app_requests.append(app_request)

    return app_requests

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

    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.
      NO_OP = 3 # Request does not require a payload response.

    def __init__(self, request_type, appid, ping=False, version=None,
                 delta_okay=None, event_type=None, event_result=None):
      """Initializes a Request.

      Args:
        request_type: install, update, or no-op.
        appid: The requested appid.
        ping: True if the server should respond to a ping.
        version: Current Chrome OS version.
        delta_okay: True if an update request can accept a delta update.
        event_type: Type of event.
        event_result: Event result.

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

    def __str__(self):
      """Returns a string representation of an AppRequest."""
      if self.request_type == self.RequestType.NO_OP:
        return "{}".format(self.appid)
      elif self.request_type == self.RequestType.INSTALL:
        return "install {} v{}".format(self.appid, self.version)
      elif self.request_type == self.RequestType.UPDATE:
        return "{} update {} from v{}".format(
            "delta" if self.delta_okay else "full", self.appid, self.version)

    def IsValid(self):
      """Returns true if an AppRequest is valid, False otherwise."""
      return None not in (self.request_type, self.appid, self.version)

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

    Args:
      request: Request instance describing client requests.
      update_index: Index of update payloads.
      install_index: Index of install payloads.
      payload_addr: Address of payload server.
    """
    self._request = request
    self._update_index = update_index
    self._install_index = install_index
    self._payload_addr = payload_addr

    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.fromstring(
          XMLResponseTemplates.RESPONSE_TEMPLATE)
      response_xml.find("daystart").set("elapsed_days", str(self._elapsed_days))
      response_xml.find(
          "daystart").set("elapsed_seconds", str(self._elapsed_seconds))

      for app_request in self._request.ParseRequest():
        logging.debug("Request for appid %s", str(app_request))
        response_xml.append(self.AppResponse(
            app_request,
            self._update_index,
            self._install_index,
            self._payload_addr).Compile())

    except Exception as err:
      logging.error("Failed to compile response (%s)", str(err))
      raise

    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, update_index, install_index, payload_addr):
      """Initialize an AppResponse.

      Attributes:
        app_request: AppRequest representing a client request.
        update_index: Index of update payloads.
        install_index: Index of install payloads.
        payload_addr: Address serving payloads.
      """
      _INSTALL_PATH = "/install/"
      _UPDATE_PATH = "/update/"

      self._app_request = app_request
      self._app_data = None
      self._payload_url = None
      self._err_not_found = False

      if self._app_request.request_type == \
          self._app_request.RequestType.INSTALL:
        self._app_data = install_index.Find(self._app_request)
        self._payload_url = payload_addr + _INSTALL_PATH
        self._err_not_found = self._app_data is None
      elif self._app_request.request_type == \
          self._app_request.RequestType.UPDATE:
        self._app_data = update_index.Find(self._app_request)
        self._payload_url = payload_addr + _UPDATE_PATH
        # 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 update_index.Contains(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 appid %s", self._app_request.appid)
      elif self._app_request.request_type == \
          self._app_request.RequestType.UPDATE:
        logging.debug("No updates available for %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.fromstring(XMLResponseTemplates.APP_TEMPLATE)
      app_response.set('appid', self._app_request.appid)

      if self._app_request.ping:
        app_response.append(
            ElementTree.fromstring(XMLResponseTemplates.PING_RESPONSE))
      if self._app_request.event_type is not None:
        app_response.append(
            ElementTree.fromstring(XMLResponseTemplates.EVENT_RESPONSE))

      if self._app_data is not None:
        app_response.set('status', 'ok')
        app_response.append(
            ElementTree.fromstring(XMLResponseTemplates.UPDATE_CHECK_TEMPLATE))
        urls = app_response.find('./updatecheck/urls')
        urls.append(
            ElementTree.Element('url', attrib={'codebase': self._payload_url}))
        manifest = app_response.find('./updatecheck/manifest')
        manifest.set('version', self._app_data.version)
        actions = manifest.findall('./actions/action')
        actions[0].set('run', self._app_data.name)
        actions[1].set('ChromeOSVersion', self._app_data.version)
        actions[1].set(
            'IsDeltaPayload', 'true' if self._app_data.is_delta else 'false')
        actions[1].set('MetadataSignatureRsa', self._app_data.metadata_sig)
        actions[1].set('MetadataSize', str(self._app_data.metadata_size))
        package = manifest.find('./packages/package')
        package.set('fp', "1.%s" % self._app_data.sha256_hash)
        package.set('hash_sha256', self._app_data.sha256_hash)
        package.set('name', self._app_data.name)
        package.set('size', str(self._app_data.size))
      elif self._err_not_found:
        app_response.set('status', XMLResponseTemplates.ERROR_NOT_FOUND)
      elif self._app_request.request_type == \
          self._app_request.RequestType.UPDATE:
        app_response.set('status', "ok")
        app_response.append(ElementTree.fromstring(
            XMLResponseTemplates.UPDATE_CHECK_NO_UPDATE))

      return app_response


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_sig'
  METADATA_SIZE_KEY = 'metadata_size'
  VERSION_KEY = 'version'
  SRC_VERSION_KEY = 'source_ver'
  SHA256_HASH_KEY = 'hash_sha256'

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

    Args:
      app_data: Dictionary containing attributes used to init 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_sig: Metadata signature.
      metadata_size: Metadata size.
      sha256_hash: SHA256 hash of the payload encoded in hexadecimal.
      version: ChromeOS version the payload is tied to.
      src_version: Source version for delta updates.
    """
    self.appid = app_data[self.APPID_KEY]
    self.name = app_data[self.NAME_KEY]
    self.version = app_data[self.VERSION_KEY]
    self.is_delta = app_data[self.IS_DELTA_KEY]
    self.src_version = (
        app_data[self.SRC_VERSION_KEY] if self.is_delta else None)
    self.size = app_data[self.SIZE_KEY]
    self.metadata_sig = app_data[self.METADATA_SIG_KEY]
    self.metadata_size = app_data[self.METADATA_SIZE_KEY]
    self.sha256_hash = app_data[self.SHA256_HASH_KEY]
    self.url = None # Determined per-request.

  def __str__(self):
    if self.is_delta:
      return "{} v{}: delta update from base v{}".format(
          self.appid, self.version, self.src_version)
    return "{} v{}: full update/install".format(
        self.appid, self.version)

  def MatchRequest(self, request):
    """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, and the source versions must match.
    If the request is not an update, the versions must match.

    Args:
      request: A request object describing a client request.

    Returns:
      True if the app matches the given request, False otherwise.
    """
    # TODO(chowes): We only account for tip/branch versions. We need to be able
    # to handle full version strings as well as developer builds that don't have
    # a "real" final version component.

    if self.appid != request.appid:
      return False

    try:
      if request.request_type == request.RequestType.UPDATE:
        if self.is_delta:
          if not request.delta_okay:
            return False
          if VersionCmp(request.version, self.src_version) != 0:
            return False
        return VersionCmp(request.version, self.version) < 0

      if request.request_type == request.RequestType.INSTALL:
        if self.is_delta:
          return False
        return VersionCmp(request.version, self.version) == 0

      else:
        return False

    except ValueError as err:
      logging.error("Unable to compare version strings (%s)", str(err))
      return False


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 (different versions,
  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: Dictionary of metadata describing payloads for a given appid.
    """
    self._directory = directory
    self._index = {}

  def Scan(self):
    """Invalidates the current cache and scans the directory.

    Clears the cached index and rescans the directory.
    """
    self._index.clear()

    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)
            app = AppData(metadata)

            if app.appid not in self._index:
              self._index[app.appid] = []
            self._index[app.appid].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, version, 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 matching the client request.
    matches = [app for app in self._index.get(request.appid, []) if
               app.MatchRequest(request)]

    if not matches:
      return None

    # Find the highest version out of the matching payloads.
    max_version = reduce(
        lambda a, b: a if VersionCmp(a.version, b.version) > 0
        else b, matches).version

    matches = [app for app in matches if app.version == max_version]

    # 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 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 request.appid in self._index


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

  def do_POST(self):
    """Responds to XML-formatted Omaha requests."""
    request_len = int(self.headers.getheader('content-length'))
    request_str = self.rfile.read(request_len)
    logging.debug("Received request: %s", request_str)

    request = Request(request_str)

    try:
      response = Response(
          request,
          self.server.owner.update_index,
          self.server.owner.install_index,
          self.server.owner.payload_addr)
      response_str = response.GetXMLString()
    except Exception as err:
      logging.error("Failed to handle request (%s)", str(err))
      traceback.print_exc()
      self.send_error(500, "Failed to handle incoming request")
      return

    self.send_response(200)
    self.send_header('Content-Type', 'application/xml')
    self.end_headers()
    self.wfile.write(response_str)


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, payload_addr, update_dir, install_dir, port=0):
    """Initializes a server instance.

    Args:
      payload_addr: Address and port of the payload server.
      update_dir: Directory to index for information about update payloads.
      install_dir: Directory to index for information about install payloads.
      port: Port the server should run on, 0 if the OS should assign a port.

    Attributes:
      update_index: Index of metadata files in the update directory.
      install_index: Index of metadata files in the install directory.
    """
    self._port = port
    self._httpd = None
    self._server_thread = None
    self.payload_addr = payload_addr.strip('/')
    self.update_index = AppIndex(update_dir)
    self.install_index = AppIndex(install_dir)

  def Start(self):
    """Starts a mock Omaha HTTP server."""
    self.update_index.Scan()
    self.install_index.Scan()

    self._httpd = HTTPServer(('', self.Port()), NebraskaHandler)
    self._port = self._httpd.server_port
    self._httpd.owner = self
    self._server_thread = threading.Thread(target=self._httpd.serve_forever)
    self._server_thread.start()

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

  def Port(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__)

  parser.add_argument('--update-payloads', metavar='DIR', default=None,
                      help='Directory containing payloads for updates.',
                      required=False)
  parser.add_argument('--install-payloads', metavar='DIR', default=None,
                      help='Directory containing payloads for installation.',
                      required=False)
  parser.add_argument('--port', metavar='PORT', type=int, default=0,
                      help='Port to run the server on', required=False)
  parser.add_argument('--payload-addr', metavar='URL',
                      help='Base payload URL.',
                      default="http://127.0.0.1:8080")

  return parser.parse_args(argv[1:])


def main(argv):
  logging.basicConfig(level=logging.DEBUG)
  opts = ParseArguments(argv)

  if not opts.update_payloads and not opts.install_payloads:
    logging.error("Need to specify at least one payload directory.")
    return os.EX_USAGE

  nebraska = NebraskaServer(payload_addr=opts.payload_addr,
                            update_dir=opts.update_payloads,
                            install_dir=opts.install_payloads,
                            port=opts.port)

  nebraska.Start()
  logging.info("Running on port %d. Press 'q' to quit.", nebraska.Port())

  try:
    while raw_input() != 'q':
      pass
  except(EOFError, KeyboardInterrupt, SystemExit):
    pass

  logging.info("Exiting...")
  nebraska.Stop()

  return os.EX_OK


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