#!/usr/bin/python
# -*- coding: utf8 -*-

import os
import sys
import subprocess
import tempfile
import shutil
import json
import argparse
import yaml
import logging
import re
import datetime

sys.path.insert(0, '/opt/direct-py/startrek-python-client-sni-fix')
from startrek_client import Startrek
logging.getLogger('startrek_client').setLevel(logging.CRITICAL)

sys.path.insert(0, 'opt/release_changelog')
sys.path.insert(0, '/opt/release_changelog')
import changelog_utils

"""
Получает svn-лог для конкретного релиза, при необходимости сохраняем его в аркадии
"""

if os.environ.get('SSH_MASTER_CONN_ARCADIA', ''):
    os.environ["SVN_SSH"] = "ssh -S %s" % os.environ['SSH_MASTER_CONN_ARCADIA']

SCRIPT_NAME = os.path.basename(__file__)

STARTREK_TOKEN_FILE = '/etc/direct-tokens/startrek'
with open(STARTREK_TOKEN_FILE) as fh:
    STARTREK_TOKEN = fh.readline().strip()
startrek_client = Startrek(token=STARTREK_TOKEN, useragent=SCRIPT_NAME)


DT_NOW = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
VERSION_RE = r'1\.([0-9]{7,})(?:\.([0-9]{7,}))?-[0-9]+'
ARCADIA_URL = 'svn+ssh://arcadia.yandex.ru/arc'
ARCADIA_CHANGELOGS_URL = 'svn+ssh://arcadia.yandex.ru/robots/trunk/directadmin-data/direct-release/changelogs'


def get_changelog_name_with_dest(app, custom_name, rev_l, rev_r, is_branch=False):
    changelog_name = (custom_name
                      if custom_name
                      else "%s_%s_%s%s_%s" % (app, rev_l, rev_r, "_branch" if is_branch else "", DT_NOW))
    commit_dest = os.path.join(ARCADIA_CHANGELOGS_URL, changelog_name)
    sys.stdout.write(commit_dest + '\n')
    sys.stdout.flush()
    return changelog_name, commit_dest


def main():
    parser = argparse.ArgumentParser(description='Get svn logs related to the specific release from arcadia')
    parser.add_argument('app', type=str, choices=changelog_utils.APPS_CONFIG.keys(), help='app name')
    parser.add_argument('version', type=str, help='release version')
    parser.add_argument('-t', '--ticket', type=str, help='release ticket')
    parser.add_argument('-c', '--commit', action='store_true', help='commit changelog to arcadia')
    parser.add_argument('-n', '--name', type=str, help='changelog name in arcadia')

    args = parser.parse_args()

    if args.ticket:
        release_issue = startrek_client.issues[args.ticket]
    else:
        release_issue = next(iter(startrek_client.issues.find(
            'Queue: DIRECT Type: Release Components: "%s" "Sort by": key desc' % (
                changelog_utils.APPS_CONFIG[args.app]['tracker-component']
            )
        )))

    if not release_issue:
        sys.exit("can't find release issue")

    base_rev, head_rev = re.match(VERSION_RE, args.version).groups()
    head_rev = head_rev or base_rev

    is_hotfix = head_rev != base_rev
    if is_hotfix and not args.ticket:
        sys.exit("no release to hotfix")

    old_version, old_base_rev, old_head_rev = re.search(r'\b(%s)\b' % VERSION_RE, release_issue.summary).groups()

    if not old_version:
        sys.exit("could not get version from summary '%s'\n" % release_issue.summary)

    old_head_rev = old_head_rev or old_base_rev
    exists_release_branch = args.ticket and old_head_rev != old_base_rev
    commit_dest = ''

    if not is_hotfix and not exists_release_branch:
        rev_l = old_base_rev or '0'
        rev_l = str(int(rev_l) + 1)
        rev_r = head_rev

        if args.commit:
            changelog_name, commit_dest = get_changelog_name_with_dest(args.app, args.name, rev_l, rev_r)

        svnlog = changelog_utils.get_svnlog_with_deps(args.app, rev_l, rev_r)
        changelog = changelog_utils.prettify_log(svnlog)

    elif is_hotfix:
        if not exists_release_branch and base_rev != old_head_rev:
            sys.exit("new base rev must be equal to old head rev, please update the ticket to '%s' first" % base_rev)

        rev_l = str(int(old_head_rev) + 1)
        rev_r = head_rev

        if args.commit:
            changelog_name, commit_dest = get_changelog_name_with_dest(args.app, args.name, rev_l, rev_r, is_branch=True)

        svnlog = changelog_utils.get_svnlog_from_branch(args.app, base_rev, rev_l, rev_r)
        changelog = changelog_utils.prettify_log(svnlog)

    elif not is_hotfix and exists_release_branch:
        sys.exit("can't slide when release branch exists")
    else:
        sys.exit("can't be")

    if args.commit:
        tmp_file = tempfile.NamedTemporaryFile(delete=True)
        try:
            tmp_file.write(changelog)
            tmp_file.flush()
            subprocess.check_output([
                'svn', 'import', '-m', 'upload changelog: %s' % changelog_name,
                '--force', '--encoding', 'UTF-8', tmp_file.name, commit_dest
            ])
        finally:
            tmp_file.close()
            
    else:
        print changelog


if __name__ == '__main__':
    main()
