# Copyright 2019-2020 Turner Broadcasting Inc. / WarnerMedia
# Copyright 2021 Chris Farris <chrisf@primeharbor.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import boto3
from botocore.exceptions import ClientError
from boto3.dynamodb.conditions import Key
import json
import os
import logging
import datetime
from dateutil import tz
from pprint import pprint

from .vpc import *
from .config import *

import logging
logger = logging.getLogger('antiope.ForeignAWSAccount')


class ForeignAWSAccount(object):
    """Class to represent an AWS Account """
    def __init__(self, account_id, config=None):
        """ Create a new object representing the AWS account specified by account_id """
        # Execute any parent class init()
        super(ForeignAWSAccount, self).__init__()

        self.account_id = account_id

        if config is None:
            # Assume we're able to get what we need from EnvVars
            self.config = AntiopeConfig()
        else:
            self.config = config

        # # Save these as attributes
        self.account_table = self.config.account_table

        response = self.account_table.query(
            KeyConditionExpression=Key('account_id').eq(self.account_id),
            Select='ALL_ATTRIBUTES'
        )
        try:
            self.db_record = response['Items'][0]
            # Convert the response into instance attributes
            self.__dict__.update(self.db_record)
            # self.account_name = str(self.account_name.encode('ascii', 'ignore'))
        except IndexError as e:
            raise AntiopeAccountLookupError("ID {} not found".format(account_id))
        except Exception as e:
            logger.error("Got Other error: {}".format(e))

    def __str__(self):
        """when converted to a string, become the account_id"""
        return(self.account_id)

    def __repr__(self):
        """Create a useful string for this class if referenced"""
        return("<ForeignAWSAccount {} >".format(self.account_id))

    #
    # Database functions
    #
    def update_attribute(self, key, value):
        """
        Update a specific attribute in a specific table for this account.
        key is the column, value is the new value to set
        """
        logger.info(u"Adding key:{} value:{} to account {}".format(key, value, self))
        try:
            response = self.account_table.update_item(
                Key= {
                    'account_id': self.account_id
                },
                UpdateExpression="set #k = :r",
                ExpressionAttributeNames={
                    '#k': key
                },
                ExpressionAttributeValues={
                    ':r': value,
                }
            )
        except ClientError as e:
            raise AccountUpdateError("Failed to update {} to {} in account table: {}".format(key, value, e))

    def get_attribute(self, key):
        """
        Fetches a attribute from the specificed table for the account
        """
        logger.info(u"Getting key:{} from account_table for account {}".format(key, self))
        try:
            response = self.account_table.get_item(
                Key= {
                    'account_id': self.account_id
                },
                AttributesToGet=[key]
            )
            return(response['Item'][key])
        except ClientError as e:
            raise AntiopeAccountLookupError("Failed to get {} from {} in account table: {}".format(key, self, e))
        except KeyError as e:
            raise AntiopeAccountLookupError("Failed to get {} from {} in account table: {}".format(key, self, e))

    def delete_attribute(self, key):
        """
        Delete a attribute from the specificed table for the account
        """
        logger.info(u"Deleting key:{} from account table for account {}".format(key, self))
        table = self.account_table
        try:
            response = table.update_item(
                Key= {
                    'account_id': self.account_id
                },
                UpdateExpression="remove #k",
                ExpressionAttributeNames={
                    '#k': key
                },
                # ExpressionAttributeValues={
                # ':r': value,
                # }
            )
        except ClientError as e:
            raise AntiopeAccountLookupError("Failed to get {} from {} in account table: {}".format(key, self, e))
        except KeyError as e:
            raise AntiopeAccountLookupError("Failed to get {} from {} in account table: {}".format(key, self, e))


