#!/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 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 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)
