#!/usr/bin/env python3
#
# OpenEmbedded SDK publishing tool
#
# Copyright (C) 2015-2016 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
#

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', host, 'mkdir -p %s' % destdir]
        ret = subprocess.call(cmd)
        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', target_sdk, destination]
        ret = subprocess.call(cmd)
        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 = [dest_sdk, '-p', '-y', '-d', destination]
        ret = subprocess.call(cmd)
        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:
        rm_or_not = " && rm -f %s" % dest_sdk
        if args.keep_orig:
            rm_or_not = ""
        cmd = ['ssh', host, 'sh %s -p -y -d %s%s' % (dest_sdk, destdir, rm_or_not)]
        ret = subprocess.call(cmd)
        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 .; cp .git/hooks/post-update.sample .git/hooks/post-commit; echo "*.pyc\n*.pyo\npyshtables.py" > .gitignore; fi; git config gc.auto 0; git add -A .; git config user.email "oe@oe.oe" && git config user.name "OE" && git commit -q -m "init repo" || true' % (destination, destination)
    else:
        cmd = "ssh %s 'set -e; mkdir -p %s/layers; cd %s/layers; if [ ! -e .git ]; then git init .; cp .git/hooks/post-update.sample .git/hooks/post-commit; echo '*.pyc' > .gitignore; echo '*.pyo' >> .gitignore; echo 'pyshtables.py' >> .gitignore; fi; git config gc.auto 0; git add -A .; git config user.email 'oe@oe.oe' && git config user.name 'OE' && git commit -q -m \"init repo\" || true'" % (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('-k', '--keep-orig', help='When published to a remote host, the eSDK installer gets deleted by default.', 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)
