"""Utilities to help test AWS Lambda functions."""

import base64

import mock


DEFAULT_INVOKED_FUNCTION_ARN = (
  'arn:aws:lambda:us-west-2:043714768218:function:{}')
DEFAULT_AWS_REQUEST_ID = '3739f59d-cc72-48c5-8af9-6df9f6093246'
DEFAULT_LOG_GROUP_NAME = '/aws/lambda/{}'
DEFAULT_LOG_STREAM_NAME = '2016/08/19/[{}]61cec2d448b24a7e9d6b3b217ea67e6d'


def Context(function_name='function_name', function_version='$LATEST',
            remaining_time_in_millis=2999, memory_limit_in_mb='128',
            invoked_function_arn=None, aws_request_id=None,
            log_group_name=None, log_stream_name=None):
    """Make Mock conforming to the "context" passed into Lambda handlers.

    Args:
      function_name: string, defaults to "function_name"
      function_version: string, defaults to "$LATEST"
      remaining_time_in_millis: int, defaults to 2999
      memory_limit_in_mb: string, defaults to "128"
      invoked_function_arn: optional string
      aws_request_id: optional string
      log_group_name: optional string
      log_stream_name: optional string

    Returns:
      MagicMock object with spec set.
    """
    context = mock.MagicMock(
        spec_set=('get_remaining_time_in_millis', 'function_name',
                  'function_version', 'invoked_function_arn',
                  'memory_limit_in_mb', 'aws_request_id', 'log_group_name',
                  'log_stream_name', 'identity', 'client_context'))
    context.get_remaining_time_in_millis.return_value = (
      remaining_time_in_millis)
    context.function_name = function_name
    context.function_version = function_version
    context.invoked_function_arn = (
      invoked_function_arn or DEFAULT_INVOKED_FUNCTION_ARN.format(
        function_name))
    context.memory_limit_in_mb = memory_limit_in_mb
    context.aws_request_id = aws_request_id or DEFAULT_AWS_REQUEST_ID
    context.log_group_name = (
      log_group_name or DEFAULT_LOG_GROUP_NAME.format(function_name))
    context.log_stream_name = (
      log_stream_name or DEFAULT_LOG_STREAM_NAME.format(function_version))
    context.client_context = None
    # context.identity will inherit a MagicMock object.
    return context


def KinesisLambdaEvent(payloads):
    sequence_num = '49564934023862930110117760110897781061359846430875844610'
    return {
      'Records': [
        {
          'eventVersion': '1.0',
          'eventID': 'shardId-000000000000:{}'.format(sequence_num),
          'kinesis': {
            'approximateArrivalTimestamp': 1471643067.111,
            'partitionKey': '0',
            'data': base64.b64encode(payload),
            'kinesisSchemaVersion': '1.0',
            'sequenceNumber': sequence_num
          },
          'invokeIdentityArn': 'arn:aws:iam::043714768218:role/role-name',
          'eventName': 'aws:kinesis:record',
          'eventSourceARN': ('arn:aws:kinesis:us-west-2:043714768218:'
                             'stream/kinesis-stream-name'),
          'eventSource': 'aws:kinesis',
          'awsRegion': 'us-west-2'
        } for payload in payloads
      ]
    }


def APIGatewayProxyLambdaEvent(body, path='/', method='POST', headers=None):
    headers = headers or {
        "CloudFront-Is-Desktop-Viewer": "true",
        "CloudFront-Is-SmartTV-Viewer": "false",
        "CloudFront-Forwarded-Proto": "https",
        "X-Forwarded-For": "52.11.36.254, 205.251.214.59",
        "CloudFront-Viewer-Country": "US",
        "Accept": "*/*",
        "User-Agent": "GitHub-Hookshot/48af271",
        "Host": "blz3tajvmc.execute-api.us-west-2.amazonaws.com",
        "X-Forwarded-Proto": "https",
        "CloudFront-Is-Tablet-Viewer": "false",
        "X-Forwarded-Port": "443",
        "CloudFront-Is-Mobile-Viewer": "false",
        "content-type": "application/json",
    }
    return {
        "body": body,
        "resource": path,
        "requestContext": {
            "resourceId": "w7207l",
            "apiId": "blz3tajvmc",
            "resourcePath": path,
            "httpMethod": method,
            "requestId": "e3580bea-851e-11e6-b1b3-41f6b428178e",
            "accountId": "043714768218",
            "identity": {
                "apiKey": None,
                "userArn": None,
                "cognitoAuthenticationType": None,
                "caller": None,
                "userAgent": "GitHub-Hookshot/48af271",
                "user": None,
                "cognitoIdentityPoolId": None,
                "cognitoIdentityId": None,
                "cognitoAuthenticationProvider": None,
                "sourceIp": "52.11.36.254",
                "accountId": None
            },
            "stage": "production"
        },
        "queryStringParameters": None,
        "httpMethod": method,
        "pathParameters": None,
        "headers": headers,
        "stageVariables": None,
        "path": path,
    }


def ScheduledLambdaEvent():
    return {
      "account": "123456789012",
      "region": "us-west-2",
      "detail": {},
      "detail-type": "Scheduled Event",
      "source": "aws.events",
      "time": "1970-01-01T00:00:00Z",
      "id": "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c",
      "resources": [
        "arn:aws:events:us-west-2:123456789012:rule/my-schedule"
      ]
    }
