# -*- coding: utf-8 -*-
# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""A Nebraska Wrapper to handle update client requests."""

from __future__ import print_function

import os
import re
import shutil
import tempfile

import requests
from six.moves import urllib

import cherrypy  # pylint: disable=import-error

# Nebraska.py has been added to PYTHONPATH, so gs_archive_server should be able
# to import nebraska.py directly. But if gs_archive_server is triggered from
# ~/chromiumos/src/platform/dev, it will import nebraska, the python package,
# instead of nebraska.py, thus throwing an AttributeError when the module is
# eventually used. To mitigate this, catch the exception and import nebraska.py
# from the nebraska package directly.
try:
  import nebraska
  nebraska.QueryDictToDict({})
except AttributeError as e:
  from nebraska import nebraska

from chromite.lib import cros_logging as logging


# Define module logger.
_logger = logging.getLogger(__file__)

# Define all GS Cache related constants.
GS_CACHE_PORT = '8888'
GS_ARCHIVE_BUCKET = 'chromeos-image-archive'
GS_CACHE_DWLD_RPC = 'download'
GS_CACHE_LIST_DIR_RPC = 'list_dir'


def _log(*args, **kwargs):
  """A wrapper function of logging.debug/info, etc."""
  level = kwargs.pop('level', logging.DEBUG)
  _logger.log(level, extra=cherrypy.request.headers, *args, **kwargs)


class NebraskaWrapperError(Exception):
  """Exception class used by this module."""


class NebraskaWrapper(object):
  """Class that contains functionality that handles Chrome OS update pings."""

  # Define regexes for properties file. These patterns are the same as the ones
  # defined in chromite/lib/xbuddy/build_artifact.py. Only the '.*' in the
  # beginning and '$' at the end is different as in this class, we need to
  # compare the full gs URL of the file without a newline at the end to this
  # regex pattern.
  _FULL_PAYLOAD_PROPS_PATTERN = r'.*chromeos_.*_full_dev.*bin(\.json)$'
  _DELTA_PAYLOAD_PROPS_PATTERN = r'.*chromeos_.*_delta_dev.*bin(\.json)$'

  def __init__(self, label, server_addr, full_update):
    """Initializes the class.

    Args:
      label: Label (string) for the update, typically in the format
          <board>-<XXXX>/Rxx-xxxxx.x.x-<unique string>.
      server_addr: IP address (string) for the server on which gs cache is
          running.
      full_update: Indicates whether the requested update is full or delta. The
          string values for this argument can be 'True', 'False', or
          'unspecified'.
    """
    self._label = self._GetLabel(label)
    self._gs_cache_base_url = 'http://%s:%s' % (server_addr, GS_CACHE_PORT)

    # When full_update parameter is not specified in the request, the update
    # type is 'delta'.
    self._is_full_update = full_update.lower().strip() == 'true'

    self._props_dir = tempfile.mkdtemp(prefix='gsc-update')
    self._payload_props_file = None

  def __enter__(self):
    """Called while entering context manager; does nothing."""
    return self

  def __exit__(self, exc_type, exc_value, traceback):
    """Called while exiting context manager; cleans up temp dirs."""
    try:
      shutil.rmtree(self._props_dir)
    except Exception as e:
      _log('Something went wrong. Could not delete %s due to exception: %s',
           self._props_dir, e, level=logging.WARNING)

  @property
  def _PayloadPropsFilename(self):
    """Get the name of the payload properties file.

    The name of the properties file is obtained from the list of files returned
    by the list_dir RPC by matching the name of the file with the update_type
    and file extension.

    Returns:
      Name of the payload properties file.

    Raises:
      NebraskaWrapperError if the list_dir calls returns 4xx/5xx or if the
          correct file could not be determined.
    """
    if self._payload_props_file:
      return self._payload_props_file

    urlbase = self._GetListDirURL()
    url = urllib.parse.urljoin(urlbase, self._label)

    resp = requests.get(url)
    try:
      resp.raise_for_status()
    except Exception as e:
      raise NebraskaWrapperError('An error occurred while trying to complete '
                                 'the request: %s' % e)

    if self._is_full_update:
      pattern = re.compile(self._FULL_PAYLOAD_PROPS_PATTERN)
    else:
      pattern = re.compile(self._DELTA_PAYLOAD_PROPS_PATTERN)

    # Iterate through all listed files to determine the correct payload
    # properties file. Since the listed files will be in the format
    # gs://<gs_bucket>/<board>/<version>/<filename>, return the filename only
    # once a match is determined.
    for fname in [x.strip() for x in resp.content.strip().split('\n')]:
      if pattern.match(fname):
        self._payload_props_file = fname.rsplit('/', 1)[-1]
        return self._payload_props_file

    raise NebraskaWrapperError(
        'Request to %s returned a %s but gs_archive_server was unable to '
        'determine the name of the properties file.' %
        (url, resp.status_code))

  def _GetLabel(self, label):
    """Gets the label for the request.

    Removes a trailing /au_nton from the label argument.

    Args:
      label: A string obtained from the request.

    Returns:
      A string in the format <board>-<XXXX>/Rxx-xxxxx.x.x-<unique string>.
    """
    # TODO(crbug.com/1102552): Remove this logic once all clients stopped
    # sending au_nton in the request.
    return label[:-len('/au_nton')] if label.endswith('/au_nton') else label

  def _GetDownloadURL(self):
    """Returns the static url base that should prefix all payload responses."""
    _log('Handling update ping as %s', self._gs_cache_base_url)
    return self._GetURL(GS_CACHE_DWLD_RPC)

  def _GetListDirURL(self):
    """Returns the static url base that should prefix all list_dir requests."""
    _log('Using base URL to list contents: %s', self._gs_cache_base_url)
    return self._GetURL(GS_CACHE_LIST_DIR_RPC)

  def _GetURL(self, rpc_name):
    """Construct gs_cache URL for the given RPC.

    Args:
      rpc_name: Name of the RPC for which the URL needs to be built.

    Returns:
      Base URL to be used.
    """
    urlbase = urllib.parse.urljoin(self._gs_cache_base_url,
                                   '%s/%s/' % (rpc_name, GS_ARCHIVE_BUCKET))
    _log('Using static url base %s', urlbase)
    return urlbase

  def _GetPayloadPropertiesDir(self, urlbase):
    """Download payload properties file from GS Archive

    Args:
      urlbase: Base url that should be used to form the download request.

    Returns:
      The path to the /tmp directory which stores the payload properties file
          that nebraska will use.

    Raises:
      NebraskaWrapperError is raised if the method is unable to
          download the file for some reason.
    """
    local_payload_dir = self._props_dir
    partial_url = urllib.parse.urljoin(urlbase, '%s/' % self._label)
    _log('Downloading %s from bucket %s.', self._PayloadPropsFilename,
         partial_url, level=logging.INFO)

    try:
      resp = requests.get(urllib.parse.urljoin(partial_url,
                                               self._PayloadPropsFilename))
      resp.raise_for_status()
      file_path = os.path.join(local_payload_dir, self._PayloadPropsFilename)
      # We are not worried about multiple threads writing to the same file as
      # we are creating a different directory for each initialization of this
      # class anyway.
      with open(file_path, 'wb') as f:
        f.write(resp.content)
    except Exception as e:
      raise NebraskaWrapperError('An error occurred while trying to complete '
                                 'the request: %s' % e)
    _log('Path to downloaded payload properties file: %s' % file_path)
    return local_payload_dir

  def HandleUpdatePing(self, data, **kwargs):
    """Handles an update ping from an update client.

    Args:
      data: XML blob from client.
      kwargs: The map of query strings passed to the /update API.

    Returns:
      Update payload message for client.
    """
    # Get the static url base that will form that base of our update url e.g.
    # http://<GS_CACHE_IP>:<GS_CACHE_PORT>/download/chromeos-image-archive/.
    urlbase = self._GetDownloadURL()
    # Change the URL's string query dictionary provided by cherrypy to a
    # valid dictionary that has proper values for its keys. e.g. True
    # instead of 'True'.
    kwargs = nebraska.QueryDictToDict(kwargs)

    try:
      # Process attributes of the update check.
      request = nebraska.Request(data)
      if request.request_type == nebraska.Request.RequestType.EVENT:
        _log('A non-update event notification received. Returning an ack.',
             level=logging.INFO)
        n = nebraska.Nebraska()
        n.UpdateConfig(**kwargs)
        return n.GetResponseToRequest(request)

      _log('Update Check Received.')

      base_url = urllib.parse.urljoin(urlbase, '%s/' % self._label)
      _log('Responding to client to use url %s to get image', base_url,
           level=logging.INFO)

      local_payload_dir = self._GetPayloadPropertiesDir(urlbase=urlbase)
      _log('Using %s as the update_metadata_dir for NebraskaProperties.',
           local_payload_dir)

      n = nebraska.Nebraska()
      n.UpdateConfig(update_payloads_address=base_url,
                     update_app_index=nebraska.AppIndex(local_payload_dir))
      return n.GetResponseToRequest(request)

    except Exception as e:
      raise NebraskaWrapperError('An error occurred while processing the '
                                 'update request: %s' % e)
