# -*- coding: utf-8 -*-
# Copyright 2011 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Devserver module for handling update client requests."""

from __future__ import print_function

import logging
import os

import cherrypy  # pylint: disable=import-error
from six.moves import urllib


# TODO(crbug.com/872441): We try to import nebraska from different places
# because when we install the devserver, we copy the nebraska.py into the main
# directory. Once this bug is resolved, we can always import from nebraska
# directory.
try:
    from nebraska import nebraska
except ImportError:
    import nebraska


# Module-local log function.
def _Log(message, *args):
    return logging.info(message, *args)


class AutoupdateError(Exception):
    """Exception classes used by this module."""

    # pylint: disable=unnecessary-pass
    pass


def _ChangeUrlPort(url, new_port):
    """Return the URL passed in with a different port"""
    scheme, netloc, path, query, fragment = urllib.parse.urlsplit(url)
    host_port = netloc.split(":")

    if len(host_port) == 1:
        host_port.append(new_port)
    else:
        host_port[1] = new_port

    print(host_port)
    netloc = "%s:%s" % tuple(host_port)

    # pylint: disable=too-many-function-args
    return urllib.parse.urlunsplit((scheme, netloc, path, query, fragment))


def _NonePathJoin(*args):
    """os.path.join that filters None's from the argument list."""
    return os.path.join(*[x for x in args if x is not None])


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

    def __init__(self, xbuddy, static_dir=None):
        """Initializes the class.

        Args:
          xbuddy: The xbuddy path.
          static_dir: The path to the devserver static directory.
        """
        self.xbuddy = xbuddy
        self.static_dir = static_dir

    def GetDevserverUrl(self):
        """Returns the devserver url base."""
        x_forwarded_host = cherrypy.request.headers.get("X-Forwarded-Host")
        if x_forwarded_host:
            # Select the left most <ip>:<port> value so that the request is
            # forwarded correctly.
            x_forwarded_host = [x.strip() for x in x_forwarded_host.split(",")][
                0
            ]
            hostname = "http://" + x_forwarded_host
        else:
            hostname = cherrypy.request.base

        return hostname

    def GetStaticUrl(self):
        """Returns the static url base that should prefix all payload responses."""
        hostname = self.GetDevserverUrl()
        _Log("Handling update ping as %s", hostname)

        static_urlbase = "%s/static" % hostname
        _Log("Using static url base %s", static_urlbase)
        return static_urlbase

    def GetBuildID(self, label, board):
        """Find the build id of the given lable and board.

        Args:
          label: from update request
          board: from update request

        Returns:
          The build id of given label and board. e.g. reef-release/R88-13591.0.0

        Raises:
          AutoupdateError: If the update could not be found.
        """
        label = label or ""
        label_list = label.split("/")
        if label_list[0] == "xbuddy":
            # If path explicitly calls xbuddy, pop off the tag.
            label_list.pop()
        x_label, _ = self.xbuddy.Translate(label_list, board=board)
        return x_label

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

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

        Returns:
          Update payload message for client.
        """
        # 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)

        # 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.")
            n = nebraska.Nebraska()
            n.UpdateConfig(**kwargs)
            return n.GetResponseToRequest(request)

        _Log("Update Check Received.")

        try:
            build_id = self.GetBuildID(label, request.board)
            base_url = "/".join((self.GetStaticUrl(), build_id))
            local_payload_dir = _NonePathJoin(self.static_dir, build_id)
        except AutoupdateError as e:
            # Raised if we fail to generate an update payload.
            _Log(
                "Failed to process an update request, but we will defer to "
                "nebraska to respond with no-update. The error was %s",
                e,
            )

        _Log("Responding to client to use url %s to get image", base_url)
        n = nebraska.Nebraska()
        n.UpdateConfig(
            update_payloads_address=base_url,
            update_app_index=nebraska.AppIndex(local_payload_dir),
        )
        return n.GetResponseToRequest(request)
