#!/usr/bin/env python
# vim: ai ts=4 sts=4 et sw=4
#
# Copyright (c) 2014, 2015, 2016 Samsung Electronics.Co.Ltd.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; version 2 of the License
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
import os
import re
import sys
import requests
import subprocess
import ast
from argparse import ArgumentParser
from common.buildtrigger import trigger_next


class trigger_for_sync_repo(object):

    profile = None
    mirror_root = os.getenv('PATH_REPO_BASE')
    pattern = r'tizen[0-9a-zA-Z_\-\.]*[0-9]{8}.[0-9]{1,2}'

    def parse_args(self):
        parser = ArgumentParser('trigger_for_sync_repo')
        parser.add_argument('profile',
                            help='tizen profile name',
                            type=str)
        parser.add_argument('-u', '--username',
                            help='snapshot server username',
                            type=str)
        parser.add_argument('-p', '--password',
                            help='snapshot server password',
                            type=str)
        parser.add_argument('-d', '--sync_repo_start_delay',
                            help='delay for repo_sync',
                            type=str)
        parser.add_argument('-s', '--snapshot_version',
                            help='snapshot version',
                            type=str)
        return parser.parse_args()

    def setup_profile_from_args(self, args):


        if os.getenv('SYNC_REPO_PROFILES'):
            self.profiles = ast.literal_eval(os.getenv('SYNC_REPO_PROFILES'))
        else:
            return False

        # set up profile
        for l in self.profiles:
            if args.profile.lower() == l['name']:
                self.profile = l
                break

        # update username
        if args.username:
            self.profile['snapshot_username'] = args.username

        # update password
        if args.password:
            self.profile['snapshot_password'] = args.password

        # update sync-start-delay
        if args.sync_repo_start_delay:
            self.profile['sync_repo_start_delay'] = args.sync_repo_start_delay

        # update snapshot_version
        if args.snapshot_version:
            self.profile['snapshot_version'] = args.snapshot_version

        return self.profile

    def get_latest_snapshot_version(self, profile, timeout=5):
        p = re.compile(self.pattern)

        # get data from url
        for loop in range(10):
            try:
                f = requests.get(profile['snapshot_url'],
                                 auth=(profile['snapshot_username'],
                                       profile['snapshot_password']),
                                 timeout=timeout)
                if f.status_code == 200:
                    break
            except requests.exceptions.Timeout as e:
                print(e)
                continue
            except requests.exceptions.ConnectionError as e:
                print(e)
                continue
            except Exception as e:
                print(e)
                raise Exception('exception from get_latest_snapshot_version')
        else:
            raise Exception('can\'t get latest snapshot version')

        # return snapshot version
        return p.findall(f.text).pop()

    def run_sync_repo(self, profile):

        force_trigger = False

        # if snapshot_version does not exists in profile, get latest snapshot version
        if not 'snapshot_version' in profile:
            profile['snapshot_version'] = self.get_latest_snapshot_version(profile)
        else:
            force_trigger = True

        path = os.path.join(os.path.join(self.mirror_root,
                                         profile['dest_dir']),
                            profile['snapshot_version'])
        if not os.path.exists(path) or force_trigger:
            print('-----[trigger sync_repo job for {} ]-----'.format(profile['snapshot_version']))

            # SR-SYNC trigger
            if os.getenv('SR_SYNC_ENABLED', '0') == '1':
                trigger_next('SUBMIT_REQUEST_SYNC_{}'.format(profile['snapshot_version']), \
                             profile, \
                             extra_params={'UPSTREAM_OBS_PROJECT': profile['project'], \
                                           'UPSTREAM_SNAPSHOT': profile['snapshot_version'], \
                                           'UPSTREAM_REASON': 'SR-SYNC'})

            ret_val = subprocess.call('mkdir -p {}'.format(path), shell=True)
            if int(ret_val) == 0:
                trigger_next('sync_repo_{}'.format(profile['name']), profile)
            else:
                print 'You got errors. %s' % ret_val
                return int(ret_val)

    def main(self):

        print('-----[JOB STARTED: trigger_for_sync_repo ]-----')
        args = self.parse_args()
        profile = self.setup_profile_from_args(args)
        self.run_sync_repo(profile)


if __name__ == '__main__':
    try:
        trigger = trigger_for_sync_repo()
        sys.exit(trigger.main())
    except Exception as e:
        print(e)
        sys.exit(1)
