import logging
import stripe
import urlparse
import json

from flask import request, make_response, Blueprint

from data import model
from data.queue import dockerfile_build_queue
from auth.auth import process_auth
from auth.permissions import ModifyRepositoryPermission
from util.invoice import renderInvoiceToHtml
from util.email import send_invoice_email
from util.names import parse_repository_name
from util.http import abort
from endpoints.trigger import BuildTrigger, ValidationRequestException


logger = logging.getLogger(__name__)

webhooks = Blueprint('webhooks', __name__)


@webhooks.route('/stripe', methods=['POST'])
def stripe_webhook():
  request_data = request.get_json()
  logger.debug('Stripe webhook call: %s' % request_data)

  event_type = request_data['type'] if 'type' in request_data else None
  if event_type == 'charge.succeeded':
    data = request_data['data'] if 'data' in request_data else {}
    obj = data['object'] if 'object' in data else {}
    invoice_id = obj['invoice'] if 'invoice' in obj else None
    customer_id = obj['customer'] if 'customer' in obj else None

    if invoice_id and customer_id:
      # Find the user associated with the customer ID.
      user = model.get_user_or_org_by_customer_id(customer_id)
      if user and user.invoice_email:
        # Lookup the invoice.
        invoice = stripe.Invoice.retrieve(invoice_id)
        if invoice:
          invoice_html = renderInvoiceToHtml(invoice, user)
          send_invoice_email(user.email, invoice_html)

  return make_response('Okay')


@webhooks.route('/push/<path:repository>/trigger/<trigger_uuid>',
                methods=['POST'])
@process_auth
@parse_repository_name
def build_trigger_webhook(namespace, repository, trigger_uuid):
  logger.debug('Webhook received for %s/%s with uuid %s', namespace,
               repository, trigger_uuid)
  permission = ModifyRepositoryPermission(namespace, repository)
  if permission.can():
    try:
      trigger = model.get_build_trigger(namespace, repository, trigger_uuid)
    except model.InvalidBuildTriggerException:
      abort(404)

    handler = BuildTrigger.get_trigger_for_service(trigger.service.name)

    logger.debug('Passing webhook request to handler %s', handler)
    try:
      specs = handler.handle_trigger_request(request, trigger.auth_token,
                                             json.loads(trigger.config))
      dockerfile_id, tags, name, subdir = specs

    except ValidationRequestException:
      # This was just a validation request, we don't need to build anything
      return make_response('Okay')

    host = urlparse.urlparse(request.url).netloc
    repo = '%s/%s/%s' % (host, trigger.repository.namespace,
                         trigger.repository.name)

    token = model.create_access_token(trigger.repository, 'write')
    logger.debug('Creating build %s with repo %s tags %s and dockerfile_id %s',
                 name, repo, tags, dockerfile_id)

    job_config = {
      'docker_tags': tags,
      'repository': repo,
      'build_subdir': subdir,
      'resource_key': dockerfile_id,
    }
    build_request = model.create_repository_build(trigger.repository, token,
                                                  job_config, name, trigger)

    dockerfile_build_queue.put(json.dumps({
      'build_uuid': build_request.uuid,
      'namespace': namespace,
      'repository': repository,
    }), retries_remaining=1)

    return make_response('Okay')

  abort(403)