#!/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 %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:
        rm_or_not = " && rm -f %s" % dest_sdk
        if args.keep_orig:
            rm_or_not = ""
        cmd = "ssh %s 'sh %s -p -y -d %s%s'" % (host, dest_sdk, destdir, rm_or_not)
        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 .; 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)
