#!/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 sys
import os
import re
import errno
import subprocess

import shutil, tempfile, atexit
import ast

from common.buildtrigger import trigger_info, trigger_next
from common.utils import make_latest_link, make_base_link

def get_file_info(file):
    info = {'owner': 0, \
            'group' : 0}
    info['owner'] = os.stat(file).st_uid
    info['group'] = os.stat(file).st_gid
    return info

def create_directory(path):
    try:
        os.makedirs(path)
    except OSError as exc: # Python >2.5
        if exc.errno == errno.EEXIST and os.path.isdir(path):
            pass
        else: raise

def execute_shell(cmd, progress=False):
    print "[INFO] command : %s" % cmd
    proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    if progress:
        line_iterator = iter(proc.stdout.readline, b"")
        for line in line_iterator:
            print "    %s" % line[:-1]
    out, err = proc.communicate()
    if cmd.startswith("rsync"):
        if err:
            print "stderr: %s" % err
            return 'err'

    if err:
        print "stderr: %s" % err
        return None

    o = out.strip().split('\n')
    print "o: %s" % o
    if len(o) == 1:
        if o[0] == '':
            return None
    return o

def make_BASE_link(project, base_path, repo_path):
    """
    Make BASE Link in Snapshot repo with configuration
    """
    try:
        if os.getenv("BASE_LINK_PRJS",""):
            linkprjs = ast.literal_eval(os.getenv("BASE_LINK_PRJS"))
            for l in linkprjs:
                if project == l['prj']:
                    tizenpath = os.path.dirname(os.path.dirname(repo_path))
                    linkpath = os.path.join(base_path, tizenpath, l['base'], 'latest')
                    snapshot_path = os.path.join(base_path, repo_path)
                    base_snapshot_path = os.path.join(l['base'], os.path.basename(os.path.realpath(linkpath)))
                    print "Make BASE Link %s project ==> %s" %(project, l['base'])
                    #print "repo_path = %s" %(repo_path)
                    #print "tizenpath = %s " %(tizenpath)
                    #print "linkpath = %s" %(linkpath)
                    print "snapshot_path = %s \nbase_snapshot_path = %s \n" %(snapshot_path, base_snapshot_path)
                    make_base_link(snapshot_path, base_snapshot_path)
                    break
    except Exception, err:
        print 'Skip BASE Link ...%s' % str(err)
    return

def main():

    print '---[JOB STARTED]-------------------------'
   
    content = trigger_info(os.getenv("TRIGGER_INFO"))
    try:
        if content['project'].split(':')[0] != 'Tizen' and \
           content['project'].split(':')[0] != 'tizen' and \
           content['project'].split(':')[0] != 'Product':
            print 'Skip Sync OBS project %s' % content['project']
            return
    except Exception, err:
        print 'Skip Sync OBS project %s' % content['project']
        return

    # for prerelease and prebuild
    if content['repo_path'].find(os.getenv("PATH_REPO_BASE")) == 0:
        if content['repo_path'].count(os.getenv("PATH_REPO_BASE")) == 1:
            content['repo_path'] = content['repo_path'].replace(os.getenv("PATH_REPO_BASE"),"")
 
    rsync_url = os.path.join(os.getenv('RSYNC_SNAPSHOT'), content['repo_path'])
    origin_BASE_URL = os.getenv('URL_PUBLIC_REPO_BASE')
    copy_BASE_URL = os.getenv('RSYNC_DOWNLOAD_BASE_URL')
    if not copy_BASE_URL.endswith('/'):
        copy_BASE_URL += '/'

    print 'origin_BASE_URL:%s' %( origin_BASE_URL)
    print 'copy_BASE_URL:%s' %( copy_BASE_URL)

    copy_repo_path = os.path.join(os.getenv('PATH_REPO_COPY'), content['repo_path'])
    origin_repo_path = os.path.join(os.getenv('PATH_REPO_BASE'), content['repo_path'])

    if not os.path.isdir(copy_repo_path):
        create_directory(copy_repo_path)
        if not execute_shell( "cp -lr %s %s" % (origin_repo_path, os.path.dirname(copy_repo_path))):
            print "[INFO] Done. Copy to sync directory."
    else:
        print "[WARING] Alreadly copy snapshot. %s" % copy_repo_path
        if not execute_shell( "cp -lrf %s %s" % (origin_repo_path, os.path.dirname(copy_repo_path))):
            print "[INFO] Done. Copy to sync directory."

    #print "[INFO] Create latest link. %s" % copy_repo_path
    #make_latest_link(copy_repo_path)

    for target_dir in ('builddata/images', 'builddata/reports', 'images'):
        have_regex_file = execute_shell("find %s -name '*' ! -name '*.log' | xargs grep -l '%s' 2>/dev/null" % \
                                         (os.path.join(copy_repo_path, target_dir), origin_BASE_URL) )
        
        if not have_regex_file :
            print "[WARING] Cann't find some files. It's not formal snapshot."
            continue
        for file in have_regex_file:
            target_file = os.path.join(copy_repo_path, target_dir, file)
            print target_file
            file_info = get_file_info(target_file)
            with open(target_file, 'r') as f:
                c = f.read()
                copy_c = c.replace(origin_BASE_URL, copy_BASE_URL)

            if os.path.isfile(target_file):
                os.unlink(target_file)

            with open(target_file, 'w+') as nf:
                nf.write(copy_c)
            os.chown(target_file, file_info['owner'], file_info['group'])
            print '[INFO] Modify file to %s' % target_file

    cmd = 'rsync --compress --stats --archive --recursive --hard-links --delete --verbose --exclude="source" %s/ %s/' \
             % (os.path.dirname(copy_repo_path), os.path.dirname(rsync_url))
    print "rsync command: %s" % cmd
    if execute_shell(cmd, progress=True) == 'err':
        cmd = 'rsync --compress --stats --archive --recursive --hard-links --delete --verbose --exclude="source" %s/ %s/' \
             % (os.path.dirname(os.path.dirname(copy_repo_path)), os.path.dirname(os.path.dirname(rsync_url)))
        if execute_shell(cmd, progress=True) == 'err':
            print "[INFO] Create latest link. %s" % copy_repo_path
            make_latest_link(copy_repo_path)
            ## Make BASE Link in Snapshot repo
            make_BASE_link(content.get('project'), os.getenv('PATH_REPO_COPY'), content.get('repo_path'))
            execute_shell(cmd, progress=True)
            content['repo_path'] = origin_repo_path
            trigger_next("build_log_parser", content)
            raise Exception('[Error] rsync failed.')

    print "[INFO] Create latest link. %s" % copy_repo_path
    make_latest_link(copy_repo_path)

    ## Make BASE Link in Snapshot repo
    make_BASE_link(content.get('project'), os.getenv('PATH_REPO_COPY'), content.get('repo_path'))

    execute_shell(cmd, progress=True)
    
if __name__ == '__main__':
    sys.exit(main())
