#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
"""

import sys
#sys.path.insert(0, '/opt/direct-py/startrek-python-client-sni-fix')
import os
import argparse
import requests
import json
from collections import OrderedDict
import tempfile
import shutil
import subprocess


ABC_API_URL = 'https://abc-back.yandex-team.ru/api/v4/resources/consumers/?service=169&with_childs=1'
SVN_PATH = ''
OAUTH_HEADER = {}

def fetch_abc_resources(url, dest):
    headers = OAUTH_HEADER

    resp = requests.get(url, headers=headers, timeout=5)
    resp.raise_for_status()
    resp = resp.json()

    for item in resp['results']:
        if item['state'] != u'granted':
            continue
        abc_res = item['resource']
 
        new_res = {}
        try:
            new_res['kind'] = abc_res['name']
            # эвристика если не "полка или сервер" - пропускаем
            if not (new_res['kind'][0].isalpha() or (new_res['kind'][0].isdigit() and new_res['kind'][1].isdigit() and new_res['kind'][2] == '/')):
                continue

            new_res['abc_id'] = int(abc_res['id'])
            new_res['bot_id'] = int(abc_res['external_id'])

            new_res['attrs'] = {}
            for attr in abc_res['attributes']:
               new_res['attrs'][attr['name']] = attr['value']
        except Exception as e:
            continue

        if not any(new_res['attrs'].get('location', '').startswith(x) for x in ['RU>', 'FI>']):
            continue

        bot_res = requests.get('http://bot.yandex-team.ru/api/consistof.php?inv=%d&format=json' % int(new_res['bot_id']), timeout=5)
        bot_res.raise_for_status()
        try:
            bot_res = bot_res.json()['data']
            if bot_res.get('item_segment3', '') in ['SERVERS', 'NODES']:
                new_res['type'] = 'server'
            elif bot_res.get('item_segment3', '') in ['STORAGES', 'NODE-STORAGE']:
                new_res['type'] = 'storage'
            else:
                continue
        except Exception as e:
            continue

        if new_res['type'] == 'server' and not new_res['attrs'].get('fqdn'):
            continue

        new_res['fqdn'] = new_res['attrs'].get('fqdn')
        new_res['location'] = new_res['attrs'].get('location')
        new_res.pop('attrs', None)

        bot_storages_res = requests.get('http://bot.yandex-team.ru/api/storages-by-serverinv.php?inv=%d' % int(new_res['bot_id']), timeout=5)
        bot_storages_res.raise_for_status()
        bot_storages_res_lines = bot_storages_res.text.strip().split('\n')
        if bot_storages_res_lines[0] == 'YES':
            new_res['storages'] = bot_storages_res_lines[1:]

        dest.append(new_res)
    return resp.get('next')


def run(args):
    tmpdir = ''
    res = get_direct_resources() 
    try:
        tmpdir = tempfile.mkdtemp()
        os.chdir(tmpdir)
        print(tmpdir)
        subprocess.check_call(['svn', 'co', SVN_PATH])

        os.chdir(os.path.join(tmpdir, os.path.basename(SVN_PATH)))
        subprocess.check_call(['svn', 'st'])

        with open('direct-hardware.json', 'w') as f:
            json.dump(res, f, indent=4, sort_keys=True)
 
        subprocess.call(['svn', 'add', 'direct-hardware.json'])
        subprocess.check_call(['svn', 'st'])
        if args.do:
            subprocess.check_call([
                'svn', 'commit', '-m',
                'Автоматический дамп ресурсов из abc (сделан скриптом %s с машины %s)' % (
                os.path.basename(__file__), subprocess.check_output(['hostname', '-f']).strip()
                )
            ])
            print("Changes were successfully commited")
        else:
            subprocess.check_call(['svn', 'st'])
    finally:
        if args.noremove:
            return
        shutil.rmtree(tmpdir)


def get_direct_resources():
    resources = []

    next_url = fetch_abc_resources(ABC_API_URL, resources)
    while next_url:
        next_url = fetch_abc_resources(next_url, resources)

    resources = sorted(resources, key=lambda kv: kv['abc_id'])
    return resources


def parse_args():
    global SVN_PATH

    parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter, description=__doc__)
    parser.add_argument('-t', '--token', default="~/.tools-oauth", help='путь до oauth токена')
    parser.add_argument('-u', '--user', type=str, help='пользователь, от которого ходить в svn')
    parser.add_argument('--arcadia-key', type=str, help='путь до пользовательского ключа для аркадии')
    parser.add_argument(
        '--do', default=False, action='store_true',
        help='привезти изменения, иначе просто выводится информация'
    )
    parser.add_argument(
        '--noremove', default=False, action='store_true',
        help='не удалять временную директорию после коммита'
    )
    args = parser.parse_args()

    SVN_PATH = 'svn+ssh://%sarcadia.yandex.ru/robots/trunk/directadmin-data/abc-hardware' % (
        args.user + '@' if args.user else ''
    )

    if args.user and not args.arcadia_key:
        parser.error('укажите путь до ключа для пользователя %s' % args.user)
    if not args.user and args.arcadia_key:
        parser.error('укажите имя пользователя, от которого хотите сходить в svn')

    if args.arcadia_key:
        os.environ['SVN_SSH'] = 'ssh -i %s' % args.arcadia_key

    return args


def main():
    global OAUTH_HEADER
    args = parse_args()

    try:
        with open(os.path.expanduser(args.token), 'r') as fh:
            OAUTH_HEADER = {'Authorization': 'OAuth ' + fh.read().strip()}
    except:
        sys.exit("can't get oauth token")

    #print(json.dumps(get_direct_resources(), indent=4))
    run(args)

if __name__ == '__main__':
    main()

