import logging
import argparse
import time
import sys
# import os

# import arcadia

from argparse import RawTextHelpFormatter

import search.tools.devops.libs.utils as u
import saas.tools.devops.lib23.saas_entity as saas_entity

from saas.tools.devops.lib.replace_saas_hosts import replace_saas_hosts, replace_all_slots_in_DM
from saas.tools.devops.lib23.nanny_helpers import NannyService
from saas.tools.ssm.modules.gencfg_api import GencfgGroupRequest


def wait_for_new_gencfg_tag():
    client = GencfgGroupRequest()
    initial_tag = client.get_latest_tag()
    final_tag = initial_tag

    while final_tag == initial_tag:
        final_tag = client.get_latest_tag()
        time.sleep(60)

    return final_tag


def parse_cmd_args():

    description = '''
This utility helps to replace bad host in given gencfg group with another host.
Replacement host is choosen automaticaly with help of ssm/gencfg_api
'''

    epilog = '''
Trivial examples:

Production:
    ./replace_one_host --saas-service people --hosts sas1-7372.search.yandex.net sas1-5438.search.yandex.net --ticket SAAS-4464

Prestable:
    ./replace_one_host --saas-ctype prestable --saas-service test2_i024 --host sas1-4343.search.yandex.net --skip-gencfg-phase --skip-nanny-phase

Replace all hosts in testing service:
    ./replace_one_host --hosts all --saas-ctype testing --saas-service maps-media

Migrate all slots in some (prestable) service to YP:
    ./replace_one_host --saas-ctype prestable --hosts all --prestable-nanny-service-override saas_yp_cloud_prestable -d --saas-service alice_paskills_testing

See more and feel free to add your user requests at http://st.yandex-team.ru/SAAS-4319

'''

    parser = argparse.ArgumentParser(description=description, epilog=epilog, formatter_class=RawTextHelpFormatter)

    parser.add_argument(
        '-d', '--debug',
        default=False,
        action='store_true',
        help='More debug info'
    )

    parser.add_argument(
        '--gencfg-group',
        help='Gencfg group to replace host in'
    )

    parser.add_argument(
        '--nanny-service',
        help='Nanny service to replace host in'
    )

    parser.add_argument(
        '--saas-service',
        help='SaaS service to replace host in'
    )

    parser.add_argument(
        '--saas-ctype',
        help='SaaS ctype'
    )

    parser.add_argument(
        '--hosts',
        nargs='+',
        help='Hosts to replace. Special value all will replace all hosts from existing pool in DM (mostly useful in testing and prestable)'
    )

    parser.add_argument(
        '--slot',
        help='Slot to replace (will replace also all other slots in this host and service)'
    )

    parser.add_argument(
        '--ticket',
        help='Startrek ticket to link commit with'
    )

    parser.add_argument(
        '--skip-gencfg-phase',
        default=False,
        action='store_true',
        help="Skip gencfg manipulations"
    )

    parser.add_argument(
        '--skip-nanny-phase',
        default=False,
        action='store_true',
        help="Skip nanny service activation"
    )

    parser.add_argument(
        '--15',
        help="Pyatnashki mode. Automaticaly updates service to the newest topology"
    )

    parser.add_argument(
        '--wait-for-new-gencfg-tag',
        default=False,
        action='store_true',
        help="Wait for new tag in gencfg (useful if you have just commited something)"
    )

    parser.add_argument(
        '--prestable-nanny-service-override',
        help="Override nanny service in service tags.info (useful for massive prestable migrations). Works only with --hosts all option."
    )

    parser.add_argument(
        '--override-confirm-dangerous-actions',
        default=False,
        action='store_true',
        help="Override confirmations for dangerous actions in DM. Will work only with --hosts all option"
    )

    parser.add_argument(
        '--dont-restore',
        default=False,
        action='store_true',
        help="Do not restore new backends and wait for user confirmation instead"
    )

    return parser.parse_args()


def main():

    args = parse_cmd_args()

    if args.debug:
        logging.error("Config : {}".format(str(args)))
        u.logger_setup(2)
    else:
        u.logger_setup(1)

    nanny_service = NannyService(args.nanny_service) if args.nanny_service else None
    gencfg_group = args.gencfg_group or None
    target_hosts = []
    for r_host in args.hosts:
        target_hosts.extend(r_host.replace(',', ' ').split())

    try:
        target_service = saas_entity.get_unique_service(args.saas_ctype, args.saas_service, args.nanny_service, args.gencfg_group)
        if len(target_service.nanny_services) == 1:
            nanny_service = list(target_service.nanny_services)[0]
    except AssertionError:
        logging.exception("Could not guess params with SaaS entity predictor")
        sys.exit(1)

    if args.hosts == ['all']:
        logging.debug(
            "Going to replace all slots in %s@%s with nanny_service_override=%s, confirm_dangerous_actions=%s",
            target_service.ctype,
            target_service.name,
            args.prestable_nanny_service_override,
            not args.override_confirm_dangerous_actions
            )
        replace_all_slots_in_DM(
            target_service.ctype,
            target_service.name,
            args.prestable_nanny_service_override,
            confirm_dangerous_actions=not args.override_confirm_dangerous_actions,
            dont_restore=args.dont_restore
            )

    else:
        if args.wait_for_new_gencfg_tag and args.skip_gencfg_phase:
            wait_for_new_gencfg_tag()

        logging.info("Going to replace {}".format(target_hosts))
        logging.debug(
            "Replacing hosts %s in service %s nanny_service=%s, group=%s, startrek_ticket=%s, skip_gencfg_phase=%s, skip_nanny_phase=%s, dont_restore=%s",
            target_hosts, target_service.name, nanny_service, gencfg_group, args.ticket, args.skip_gencfg_phase, args.skip_nanny_phase, args.dont_restore
        )

        replace_saas_hosts(
            target_service,
            target_hosts,
            nanny_service=nanny_service,
            group=gencfg_group,
            startrek_ticket=args.ticket,
            skip_gencfg_phase=args.skip_gencfg_phase,
            skip_nanny_phase=args.skip_nanny_phase,
            dont_restore=args.dont_restore
        )


if __name__ == '__main__':
    main()
