#!/usr/bin/env python
#-*- coding: utf-8 -*-
#  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
#
#  Use of this source code is governed by a BSD-style license
#  that can be found in the LICENSE file in the root of the source
#  tree. An additional intellectual property rights grant can be found
#  in the file PATENTS.  All contributing project authors may
#  be found in the AUTHORS file in the root of the source tree.

"""Contains utilities for communicating with the dashboard."""

import httplib
import shelve
import oauth.oauth as oauth

import constants


class FailedToReadRequiredInputFile(Exception):
  pass


class FailedToReportToDashboard(Exception):
  pass


class DashboardConnection:
  """Helper class for pushing data to the dashboard.

     This class deals with most of details for accessing protected resources
     (i.e. data-writing operations) on the dashboard. Such operations are
     authenticated using OAuth. This class requires a consumer secret and a
     access token.

     The access token and consumer secrets are stored as files on disk in the
     working directory of the scripts. Both files are created by the
     request_oauth_permission script.
  """

  def __init__(self, consumer_key):
    self.consumer_key_ = consumer_key
    self.consumer_secret_ = None
    self.access_token_string_ = None

  def read_required_files(self, consumer_secret_file, access_token_file):
    """Reads required data for making OAuth requests.

       Args:
           consumer_secret_file: A shelve file with an entry consumer_secret
               containing the consumer secret in string form.
           access_token_file: A shelve file with an entry access_token
               containing the access token in string form.
    """
    self.access_token_string_ = self._read_access_token(access_token_file)
    self.consumer_secret_ = self._read_consumer_secret(consumer_secret_file)

  def send_post_request(self, url, parameters):
    """Sends an OAuth request for a protected resource in the dashboard.

       Use this when you want to report new data to the dashboard. You must have
       called the read_required_files method prior to calling this method, since
       that method will read in the consumer secret and access token we need to
       make the OAuth request. These concepts are described in the class
       description.

       The server is expected to respond with HTTP status 200 and a completely
       empty response if the call failed. The server may put diagnostic
       information in the response.

       Args:
           url: An absolute url within the dashboard domain, for example
               http://webrtc-dashboard.appspot.com/add_coverage_data.
           parameters: A dict which maps from POST parameter names to values.

       Raises:
           FailedToReportToDashboard: If the dashboard didn't respond
               with HTTP 200 to our request or if the response is non-empty.
    """
    consumer = oauth.OAuthConsumer(self.consumer_key_, self.consumer_secret_)
    access_token = oauth.OAuthToken.from_string(self.access_token_string_)

    oauth_request = oauth.OAuthRequest.from_consumer_and_token(
                        consumer,
                        token=access_token,
                        http_method='POST',
                        http_url=url,
                        parameters=parameters)

    signature_method_hmac_sha1 = oauth.OAuthSignatureMethod_HMAC_SHA1()
    oauth_request.sign_request(signature_method_hmac_sha1, consumer,
                               access_token)

    connection = httplib.HTTPConnection(constants.DASHBOARD_SERVER)

    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    connection.request('POST', url, body=oauth_request.to_postdata(),
                       headers=headers)

    response = connection.getresponse()
    connection.close()

    if response.status != 200:
      message = ('Failed to report to %s: got response %d (%s)' %
                 (url, response.status, response.reason))
      raise FailedToReportToDashboard(message)

    # The response content should be empty on success, so check that:
    response_content = response.read()
    if response_content:
      message = ('Dashboard reported the following error: %s.' %
                 response_content)
      raise FailedToReportToDashboard(message)

  def _read_access_token(self, filename):
    return self._read_shelve(filename, 'access_token')

  def _read_consumer_secret(self, filename):
    return self._read_shelve(filename, 'consumer_secret')

  @staticmethod
  def _read_shelve(filename, key):
    input_file = shelve.open(filename)

    if not input_file.has_key(key):
      raise FailedToReadRequiredInputFile('Missing correct %s file in current '
                                          'directory. You may have to run '
                                          'request_oauth_permission.py.' %
                                          filename)

    result = input_file[key]
    input_file.close()

    return result
