#!/usr/bin/env python

# OpenEmbedded SDK publishing tool

# Copyright (C) 2015-2016 Intel Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# 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.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import sys
import os
import argparse
import glob
import re
import subprocess
import logging
import shutil
import errno

scripts_path = os.path.dirname(os.path.realpath(__file__))
lib_path = scripts_path + '/lib'
sys.path = sys.path + [lib_path]
import scriptutils
import argparse_oe
logger = scriptutils.logger_create('sdktool')

def mkdir(d):
    try:
        os.makedirs(d)
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise e

def publish(args):
    logger.debug("In publish function")
    target_sdk = args.sdk
    destination = args.dest
    logger.debug("target_sdk = %s, update_server = %s" % (target_sdk, destination))
    sdk_basename = os.path.basename(target_sdk)

    # Ensure the SDK exists
    if not os.path.exists(target_sdk):
        logger.error("Specified SDK %s doesn't exist" % target_sdk)
        return -1
    if os.path.isdir(target_sdk):
        logger.error("%s is a directory - expected path to SDK installer file" % target_sdk)
        return -1

    if ':' in destination:
        is_remote = True
        host, destdir = destination.split(':')
        dest_sdk = os.path.join(destdir, sdk_basename)
    else:
        is_remote = False
        dest_sdk = os.path.join(destination, sdk_basename)
        destdir = destination

    # Making sure the directory exists
    logger.debug("Making sure the destination directory exists")
    if not is_remote:
        mkdir(destination)
    else:
        cmd = "ssh %s 'mkdir -p %s'" % (host, destdir)
        ret = subprocess.call(cmd, shell=True)
        if ret != 0:
            logger.error("Making directory %s on %s failed" % (destdir, host))
            return ret

    # Copying the SDK to the destination
    logger.info("Copying the SDK to destination")
    if not is_remote:
        if os.path.exists(dest_sdk):
            os.remove(dest_sdk)
        if (os.stat(target_sdk).st_dev == os.stat(destination).st_dev):
            os.link(target_sdk, dest_sdk)
        else:
            shutil.copy(target_sdk, dest_sdk)
    else:
        cmd = "scp %s %s" % (target_sdk, destination)
        ret = subprocess.call(cmd, shell=True)
        if ret != 0:
            logger.error("scp %s %s failed" % (target_sdk, destination))
            return ret

    # Unpack the SDK
    logger.info("Unpacking SDK")
    if not is_remote:
        cmd = "sh %s -p -y -d %s" % (dest_sdk, destination)
        ret = subprocess.call(cmd, shell=True)
        if ret == 0:
            logger.info('Successfully unpacked %s to %s' % (dest_sdk, destination))
            os.remove(dest_sdk)
        else:
            logger.error('Failed to unpack %s to %s' % (dest_sdk, destination))
            return ret
    else:
        cmd = "ssh %s 'sh %s -p -y -d %s && rm -f %s'" % (host, dest_sdk, destdir, dest_sdk)
        ret = subprocess.call(cmd, shell=True)
        if ret == 0:
            logger.info('Successfully unpacked %s to %s' % (dest_sdk, destdir))
        else:
            logger.error('Failed to unpack %s to %s' % (dest_sdk, destdir))
            return ret

    # Setting up the git repo
    if not is_remote:
        cmd = 'set -e; mkdir -p %s/layers; cd %s/layers; if [ ! -e .git ]; then git init .; mv .git/hooks/post-update.sample .git/hooks/post-update; echo "*.pyc\n*.pyo" > .gitignore; fi; git add -A .; git config user.email "oe@oe.oe" && git config user.name "OE" && git commit -q -m "init repo" || true; git update-server-info' % (destination, destination)
    else:
        cmd = "ssh %s 'set -e; mkdir -p %s/layers; cd %s/layers; if [ ! -e .git ]; then git init .; mv .git/hooks/post-update.sample .git/hooks/post-update; echo '*.pyc\n*.pyo' > .gitignore; fi; git add -A .; git config user.email 'oe@oe.oe' && git config user.name 'OE' && git commit -q -m \"init repo\" || true; git update-server-info'" % (host, destdir, destdir)
    ret = subprocess.call(cmd, shell=True)
    if ret == 0:
        logger.info('SDK published successfully')
    else:
        logger.error('Failed to set up layer git repo')
    return ret


def main():
    parser = argparse_oe.ArgumentParser(description="OpenEmbedded extensible SDK publishing tool - writes server-side data to support the extensible SDK update process to a specified location")
    parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true')
    parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true')

    parser.add_argument('sdk', help='Extensible SDK to publish (path to .sh installer file)')
    parser.add_argument('dest', help='Destination to publish SDK to; can be local path or remote in the form of user@host:/path (in the latter case ssh/scp will be used).')

    parser.set_defaults(func=publish)

    args = parser.parse_args()

    if args.debug:
        logger.setLevel(logging.DEBUG)
    elif args.quiet:
        logger.setLevel(logging.ERROR)

    ret = args.func(args)
    return ret

if __name__ == "__main__":
    try:
        ret = main()
    except Exception:
        ret = 1
        import traceback
        traceback.print_exc()
    sys.exit(ret)
