import logging
import random

from collections import namedtuple
from urlparse import urlparse

from flask import request

from app import analytics, userevents, ip_resolver
from auth.auth_context import get_authenticated_context, get_authenticated_user
from data.logs_model import logs_model

logger = logging.getLogger(__name__)

Repository = namedtuple('Repository', ['namespace_name', 'name', 'id'])

def wrap_repository(repo_obj):
  return Repository(namespace_name=repo_obj.namespace_user.username, name=repo_obj.name,
                    id=repo_obj.id)


def track_and_log(event_name, repo_obj, analytics_name=None, analytics_sample=1, **kwargs):
  repo_name = repo_obj.name
  namespace_name = repo_obj.namespace_name
  metadata = {
    'repo': repo_name,
    'namespace': namespace_name,
  }
  metadata.update(kwargs)

  # Add auth context metadata.
  analytics_id = 'anonymous'
  auth_context = get_authenticated_context()
  if auth_context is not None:
    analytics_id, context_metadata = auth_context.analytics_id_and_public_metadata()
    metadata.update(context_metadata)

  # Publish the user event (if applicable)
  logger.debug('Checking publishing %s to the user events system', event_name)
  if auth_context and auth_context.has_nonrobot_user:
    logger.debug('Publishing %s to the user events system', event_name)
    user_event_data = {
      'action': event_name,
      'repository': repo_name,
      'namespace': namespace_name,
    }

    event = userevents.get_event(auth_context.authed_user.username)
    event.publish_event_data('docker-cli', user_event_data)

  # Save the action to mixpanel.
  if random.random() < analytics_sample:
    if analytics_name is None:
      analytics_name = event_name

    logger.debug('Logging the %s to analytics engine', analytics_name)

    request_parsed = urlparse(request.url_root)
    extra_params = {
      'repository': '%s/%s' % (namespace_name, repo_name),
      'user-agent': request.user_agent.string,
      'hostname': request_parsed.hostname,
    }

    analytics.track(analytics_id, analytics_name, extra_params)

  # Add the resolved information to the metadata.
  logger.debug('Resolving IP address %s', request.remote_addr)
  resolved_ip = ip_resolver.resolve_ip(request.remote_addr)
  if resolved_ip is not None:
    metadata['resolved_ip'] = resolved_ip._asdict()

  logger.debug('Resolved IP address %s', request.remote_addr)

  # Log the action to the database.
  logger.debug('Logging the %s to logs system', event_name)
  logs_model.log_action(event_name, namespace_name, performer=get_authenticated_user(),
                        ip=request.remote_addr, metadata=metadata, repository=repo_obj)
  logger.debug('Track and log of %s complete', event_name)