#!/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 glob
import shutil
import subprocess
import tempfile

from common.buildtrigger import trigger_info, trigger_next
from common import runner

class LocalError(Exception):
    """Local error exception."""
    pass

class RuntimeException(Exception):
    """Local error handler"""
    pass

def execute(cmd, cwd = None):
    try:
        ret_code = subprocess.call(cmd, shell=True, cwd=cwd)
    except OSError as err:
        raise RuntimeException("Execution of %s failed: %s" %
                               (cmd, str(err)))
    return ret_code

def nuget_init(nuget_exe, nuget_source, nuget_apikey):
    """ Init Nuget """
    cmd = '%s setApiKey %s -Source %s' \
           % (nuget_exe, nuget_apikey, nuget_source)
    return execute(cmd)

def nuget_push(nuget_exe, nuget_source, nupkg, tmpdir):
    """ Push Nuget """
    cmd = '%s push %s -Source %s' % (nuget_exe, nupkg, nuget_source)
    return execute(cmd, tmpdir)

def extract_rpms(repodir, private=False):
    """ Extract rpms """
    if private:
        ngrpms = glob.glob(os.path.join(repodir, '*-nuget-private-[0-9]*.rpm'))
    else:
        ngrpms = glob.glob(os.path.join(repodir, '*-nuget-[0-9]*.rpm'))

    tmpdir = tempfile.mkdtemp(prefix = 'nuget')
    for rpm in ngrpms:
        execute('rpm2cpio %s | cpio -idmv' % rpm, tmpdir)
    return tmpdir

def push_nuget_files(nuget_exe, nuget_source, tmpdir):
    """ Push Nuget files """
    nupkgs = glob.glob(os.path.join(tmpdir, 'nuget/*.nupkg'))
    for nupkg in nupkgs:
        nuget_push(nuget_exe, nuget_source, os.path.relpath(nupkg, tmpdir), tmpdir)

def main():
    """ Script entry point. """
    print '---[JOB STARTED]-------------------------'

    # get trigger_info
    content = trigger_info(os.getenv("TRIGGER_INFO"))
    project = content.get("project")
    repo_path = content.get("repo_path")

    # get NUGET configuration
    if os.getenv("NUGET_UPDATE_ENABLE","0") != "1":
        print "Skipping as NUGET_UPDATE_ENABLE=%s is not enabled " \
                  %(os.getenv("NUGET_UPDATE_ENABLE"))
        return 0
    if not project in os.getenv("NUGET_PROJECT"):
        print "Skipping as %s project is not present in nuget project %s " \
                  %(project, os.getenv("NUGET_PROJECT"))
        return 0

    nuget_exe = "mono %s/jenkins-scripts/scripts/nuget.exe" %(os.getenv('WORKSPACE'))
    nuget_source = os.getenv("NUGET_SOURCE")
    nuget_source_private = os.getenv("NUGET_SOURCE_PRIVATE")
    nuget_apikey = os.getenv("NUGET_APIKEY")

    # Initialize NuGet
    nuget_init(nuget_exe, nuget_source, nuget_apikey)
    nuget_init(nuget_exe, nuget_source_private, nuget_apikey)

    if os.getenv('IMG_SYNC_DEST_BASE'):
        destdir = os.path.join(os.getenv('WORKSPACE'),
                                    'outdir')
        srcdir = os.path.join(os.getenv('IMG_SYNC_DEST_BASE'),
                              repo_path, "repos")
        cmd = "rsync %s -r --list-only --include='%s' --include='*/' --exclude='*'" \
              " | awk '{ print $5; }' | grep 'nuget' " \
              % (srcdir, "*armv7l.rpm" )
        print "cmd : %s" %(cmd)
        filelists = runner.outs(cmd).strip().split('\n')

        print "filelists : %s" %(filelists)
        file_name= "_filelist"
        content = ""

        if os.path.isfile(file_name):
            os.remove(file_name)

        with open(file_name, 'w') as f:
            for filepath in filelists:
                data = os.path.join(os.getenv('IMG_SYNC_DEST_BASE'), repo_path, filepath) + '\n'
                f.write(data)

        cmd = "cat %s | " %(file_name)
        cmd += "xargs -n 1 -P 1 -I% rsync -avz --bwlimit=5120000 % "
        cmd += "%s/" %(destdir)
        print 'cmd = %s' %(cmd)
        subprocess.call(cmd, shell=True)

        # Push .nupkg files in -nuget-*.rpm
        tmpdir = extract_rpms(destdir)
        print tmpdir
        push_nuget_files(nuget_exe, nuget_source, tmpdir)
        shutil.rmtree(tmpdir)

        # Push .nupkg files in -nuget-private-*.rpm
        tmpdir_priv = extract_rpms(destdir, private=True)
        print tmpdir_priv
        push_nuget_files(nuget_exe, nuget_source_private, tmpdir_priv)
        shutil.rmtree(tmpdir_priv)

    else:

        base_path = os.getenv('PATH_REPO_BASE')

        for repository in content.get("repo").keys():
            for arch in content.get("repo")[repository].get("archs"):
                if arch != "armv7l":
                    continue
                else:
                    repo_arch_path = os.path.join(base_path,
                                                  repo_path,
                                                  "repos",
                                                  repository,
                                                  "packages",
                                                  arch
                                                 )
                    print "repo arch path = %s" %repo_arch_path
                    # Push .nupkg files in -nuget-*.rpm
                    tmpdir = extract_rpms(repo_arch_path)
                    print tmpdir
                    push_nuget_files(nuget_exe, nuget_source, tmpdir)
                    shutil.rmtree(tmpdir)

                    # Push .nupkg files in -nuget-private-*.rpm
                    tmpdir_priv = extract_rpms(repo_arch_path, private=True)
                    print tmpdir_priv
                    push_nuget_files(nuget_exe, nuget_source_private, tmpdir_priv)
                    shutil.rmtree(tmpdir_priv)

    print '---[JOB ENDED]---------------------------'
    return 0

if __name__ == "__main__":
    try:
        sys.exit(main())
    except LocalError, error:
        print error
        sys.exit(1)


