#!/usr/bin/env python
# Copyright 2015-2016 Yelp Inc.
#
# 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 argparse
import datetime
import logging

import dateutil.parser
from dateutil import tz
from pytimeparse import timeparse

from paasta_tools import marathon_tools


log = logging.getLogger(__name__)


def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-a",
        "--age",
        dest="age",
        type=timedelta_type,
        default="1h",
        help="Max age of a Marathon deployment before it is stopped."
        "Any pytimeparse unit is supported",
    )
    parser.add_argument(
        "-n",
        "--dry-run",
        action="store_true",
        help="Don't actually stop any Marathon deployments",
    )
    parser.add_argument("-v", "--verbose", action="store_true")
    options = parser.parse_args()
    return options


def timedelta_type(value):
    """Return the :class:`datetime.datetime.DateTime` for a time in the past.
    :param value: a string containing a time format supported by :mod:`pytimeparse`
    """
    if value is None:
        return None
    return datetime_seconds_ago(timeparse.timeparse(value))


def datetime_seconds_ago(seconds):
    return now() - datetime.timedelta(seconds=seconds)


def now():
    return datetime.datetime.now(tz.tzutc())


def delete_deployment_if_too_old(client, deployment, max_date, dry_run):
    started_at = dateutil.parser.parse(deployment.version)
    age = now() - started_at
    if started_at < max_date:
        if dry_run is True:
            log.warning(
                f"Would delete {deployment.id} for {deployment.affected_apps[0]} as it is {age} old"
            )
        else:
            log.warning(
                f"Deleting {deployment.id} for {deployment.affected_apps[0]} as it is {age} old"
            )
            client.delete_deployment(deployment_id=deployment.id, force=False)
    else:
        if dry_run is True:
            log.warning(
                f"NOT deleting {deployment.id} for {deployment.affected_apps[0]} as it is {age} old"
            )


def main():
    args = parse_args()
    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.WARNING)

    clients = marathon_tools.get_list_of_marathon_clients()

    for client in clients:
        for deployment in client.list_deployments():
            delete_deployment_if_too_old(
                client=client,
                deployment=deployment,
                max_date=args.age,
                dry_run=args.dry_run,
            )


if __name__ == "__main__":
    main()
