# Monocyte - Search and Destroy unwanted AWS Resources relentlessly.
# Copyright 2015 Immobilien Scout GmbH
#
# 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 warnings
from boto import rds2
from monocyte.handler import Resource, Handler

SKIPPING_CREATION_STATEMENT = "Currently in creation. Skipping."
SKIPPING_AUTOGENERATED_STATEMENT = "Not a manually created Snapshot. Skipping."
SKIPPING_DELETION_STATEMENT = "Deletion already in progress. Skipping."
DELETION_STATEMENT = "Initiating deletion sequence for %s."

CREATION_STATUS = "creating"
AUTOMATED_STATUS = "automated"
DELETION_STATUS = "deleting"


class Instance(Handler):

    def fetch_region_names(self):
        return [region.name for region in rds2.regions()]

    def fetch_unwanted_resources(self):
        for region_name in self.region_names:
            connection = rds2.connect_to_region(region_name)
            resources = connection.describe_db_instances() or []
            for resource in resources["DescribeDBInstancesResponse"]["DescribeDBInstancesResult"]["DBInstances"]:
                resource_wrapper = Resource(resource=resource,
                                            resource_type=self.resource_type,
                                            resource_id=resource["DBInstanceIdentifier"],
                                            creation_date=resource["InstanceCreateTime"],
                                            region=region_name)
                if resource['DBInstanceIdentifier'] in self.ignored_resources:
                    self.logger.info('IGNORE ' + self.to_string(resource_wrapper))
                    continue
                yield resource_wrapper

    def to_string(self, resource):
        return "Database Instance found in {region}, ".format(**vars(resource)) + \
               "with name {DBInstanceIdentifier}, with status {DBInstanceStatus}".format(**resource.wrapped)

    def delete(self, resource):
        if self.dry_run:
            return
        if resource.wrapped["DBInstanceStatus"] == DELETION_STATUS:
            warnings.warn(Warning(SKIPPING_DELETION_STATEMENT))
        self.logger.info(DELETION_STATEMENT % resource.wrapped["DBInstanceIdentifier"])
        connection = rds2.connect_to_region(resource.region)
        connection.delete_db_instance(resource.wrapped["DBInstanceIdentifier"], skip_final_snapshot=True)


class Snapshot(Handler):

    def fetch_region_names(self):
        return [region.name for region in rds2.regions()]

    def fetch_unwanted_resources(self):
        for region_name in self.region_names:
            connection = rds2.connect_to_region(region_name)
            resources = connection.describe_db_snapshots() or []
            for resource in resources["DescribeDBSnapshotsResponse"]["DescribeDBSnapshotsResult"]["DBSnapshots"]:
                resource_wrapper = Resource(resource=resource,
                                            resource_type=self.resource_type,
                                            resource_id=resource["DBSnapshotIdentifier"],
                                            creation_date=resource["SnapshotCreateTime"],
                                            region=region_name)
                if resource['DBSnapshotIdentifier'] in self.ignored_resources:
                    self.logger.info('IGNORE ' + self.to_string(resource_wrapper))
                    continue
                yield resource_wrapper

    def to_string(self, resource):
        return "Database Snapshot found in {region}, ".format(**vars(resource)) + \
               "with name {DBSnapshotIdentifier}, with status {Status}".format(**resource.wrapped)

    def delete(self, resource):
        if self.dry_run:
            return
        if resource.wrapped["Status"] == DELETION_STATUS:
            warnings.warn(Warning(SKIPPING_DELETION_STATEMENT))
        if resource.wrapped["Status"] == CREATION_STATUS:
            warnings.warn(Warning(SKIPPING_CREATION_STATEMENT))
        if resource.wrapped["SnapshotType"] == AUTOMATED_STATUS:
            warnings.warn(Warning(SKIPPING_AUTOGENERATED_STATEMENT))

        self.logger.info(DELETION_STATEMENT % resource.wrapped["DBSnapshotIdentifier"])
        connection = rds2.connect_to_region(resource.region)
        connection.delete_db_snapshot(resource.wrapped["DBSnapshotIdentifier"])
