"""Functions for determining current environment and getting AWS resources."""

from __future__ import absolute_import

import re

from twitch import sandstorm
from . import errors
from . import event_bus
from . import event_store
from . import ingest_queue
from . import jira
from . import large_event_store


class Environment(object):
    """Captures what AWS resources to use for a specific environment.

    Args:
      name: string name of the environment
      region: the AWS region used for all resources of this environment
      ingest_queue: the name of the SQS queue used for ingestion requests
      event_bus: the name of the Kinesis stream for events
      event_table: name of the DynamoDB table where events are stored
      sandstorm_role: ARN of the role to assume to use Sandstorm
      jira_secret_name_prefix: prefix for names of Sandstorm secrets used
                               to get Jira credentials.
      jira_consumer_key_name: name of the consumer key configured within JIRA
      bucket_name: name of the S3 bucket
      large_event_key_prefix: where, within the S3 bucket, to store large
                              events

    Properties:
      same as the args.
    """

    def __init__(self, name, region, ingest_queue, event_bus, event_table,
                 sandstorm_role, jira_secret_name_prefix,
                 jira_consumer_key_name, bucket_name, large_event_key_prefix):
        self.name = name
        self.region = region
        self.ingest_queue = ingest_queue
        self.event_bus = event_bus
        self.event_table = event_table
        self.sandstorm_role = sandstorm_role
        self.sandstorm_secrets_cache = {}
        self.jira_secret_name_prefix = jira_secret_name_prefix
        self.jira_consumer_key_name = jira_consumer_key_name
        self.bucket_name = bucket_name
        self.large_event_key_prefix = large_event_key_prefix

    def IngestQueue(self):
        """Returns IngestQueue object."""
        return ingest_queue.IngestQueue(self.ingest_queue, self.region)

    def LargeEventStore(self):
        """Returns LargeEventStore object."""
        return large_event_store.LargeEventStore(
            self.bucket_name, self.large_event_key_prefix, self.region)

    def EventBus(self):
        """Returns EventBus object."""
        return event_bus.EventBus(
            self.event_bus, self.LargeEventStore(), self.region)

    def EventStore(self):
        """Returns EventStore object."""
        return event_store.EventStore(
            self.event_table, self.LargeEventStore(), self.region)

    def SandstormClient(self):
        """Returns SandstormClient object.

        The environment object keeps the secrets cache and creates each
        SandstormClient with it so successive calls to create SandstormClients
        will all share the same cache.
        """
        return sandstorm.SandstormClient(
          self.sandstorm_role, secrets_cache=self.sandstorm_secrets_cache)

    def JiraClient(self):
        """Returns JIRA client with server and credentials configured.

        Credentials are fetched from Sandstorm.
        """
        return jira.GetJiraClient(
          self.SandstormClient(),
          self.jira_secret_name_prefix,
          self.jira_consumer_key_name)


ENVIRONMENTS = {
  'rockpaperscissors-development': Environment(
    name='rockpaperscissors-development',
    region='us-west-2',
    ingest_queue='rockpaperscissors-development-ingest',
    event_bus='rockpaperscissors-development-events',
    event_table='rockpaperscissors-development-events',
    sandstorm_role=('arn:aws:iam::734326455073:role/sandstorm/production/'
                    'templated/role/devtools-development-rockpaperscissors'),
    jira_secret_name_prefix='rps/rockpaperscissors/development/',
    jira_consumer_key_name='rockpaperscissors',
    bucket_name='rockpaperscissors-development',
    large_event_key_prefix='large_events',
  ),
  'rockpaperscissors-production': Environment(
    name='rockpaperscissors-production',
    region='us-west-2',
    ingest_queue='rockpaperscissors-production-ingest',
    event_bus='rockpaperscissors-production-events',
    event_table='rockpaperscissors-production-events',
    sandstorm_role=('arn:aws:iam::734326455073:role/sandstorm/production/'
                    'templated/role/devtools-production-rockpaperscissors'),
    jira_secret_name_prefix='rps/rockpaperscissors/production/',
    jira_consumer_key_name='rockpaperscissors',
    bucket_name='rockpaperscissors-production',
    large_event_key_prefix='large_events',
  ),
}


def GetEnvironment(lambda_context):
    """Get environment object describing resources.

    Currently uses the lambda function name to figure out which environment
    we are currently running in. It expects the function name to start with
    "rockpaperscissors-development-" or "rockpaperscissors-production-".

    Args:
      lambda_context: context object passed into lambda handler function.

    Returns:
      Environment object.

    Raises:
      EnvironmentError if it can't determine the environment.
    """
    match = re.match(r'(rockpaperscissors-\w+)', lambda_context.function_name)
    if not (match and match.group(1) in ENVIRONMENTS):
        raise errors.EnvironmentError(
          "Couldn't determine current environment for "
          "lambda function \"{}\"".format(lambda_context.function_name))
    return ENVIRONMENTS[match.group(1)]
