# Copyright 2014 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.

"""Common Utility Methods"""

import cherrypy
import json

import common
from fake_device_server import server_errors


def parse_serialized_json():
    """Parses incoming cherrypy request as a json."""
    body_length = int(cherrypy.request.headers.get('Content-Length', 0))
    data = cherrypy.request.rfile.read(body_length)
    return json.loads(data) if data else None


def grab_header_field(header_name):
    """Returns the header |header_name| from an incoming request.

    @param header_name: Header name to retrieve.
    """
    return cherrypy.request.headers.get(header_name)


def parse_common_args(args_tuple, kwargs, supported_operations=set()):
    """Common method to parse args to a CherryPy RPC for this server.

    |args_tuple| should contain all the sections of the URL after CherryPy
    removes the pieces that dispatched the URL to this handler. For instance,
    a GET method receiving '...'/<id>/<method_name> should call:
    parse_common_args(args_tuple=[<id>, <method_name>]).
    Some operations take no arguments. Other operations take
    a single argument. Still other operations take
    one of supported_operations as a second argument (in the args_tuple).

    @param args_tuple: Tuple of positional args.
    @param kwargs: Dictionary of named args passed in.
    @param supported_operations: Set of operations to support if any.

    Returns:
        A 3-tuple containing the id parsed from the args_tuple, api_key,
        and finally an optional operation if supported_operations is provided
        and args_tuple contains one of the supported ops.

    Raises:
        server_error.HTTPError if combination or args/kwargs doesn't make
        sense.
    """
    args = list(args_tuple)
    api_key = kwargs.get('key')
    id = args.pop(0) if args else None
    operation = args.pop(0) if args else None
    if operation:
        if not supported_operations:
            raise server_errors.HTTPError(
                    400, 'Received operation when operation was not '
                    'expected: %s!' % operation)
        elif not operation in supported_operations:
            raise server_errors.HTTPError(
                    400, 'Unsupported operation: %s' % operation)

    # All expected args should be popped off already.
    if args:
        raise server_errors.HTTPError(
                400, 'Could not parse all args: %s' % args)

    return id, api_key, operation
