#!/usr/bin/env python3
"""Python Action Builder
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""

from __future__ import print_function
import os, os.path, sys, ast, shutil, subprocess, traceback
import importlib
from os.path import abspath, exists, dirname

# write a file creating intermediate directories
def write_file(file, body, executable=False):
    try: os.makedirs(dirname(file), mode=0o755)
    except: pass
    with open(file, mode="wb") as f:
        f.write(body.encode("utf-8"))
    if executable:
        os.chmod(file, 0o755)

# copy a file eventually replacing a substring
def copy_replace(src, dst, match=None, replacement=""):
    with open(src, 'rb') as s:
        body = s.read()
        if match:
            body = body.decode("utf-8").replace(match, replacement)
        write_file(dst, body)

# assemble sources
def sources(launcher, main, src_dir):
    # move exec in the right place if exists
    src_file = "%s/exec" % src_dir
    if exists(src_file):
        os.rename(src_file, "%s/__main__.py" % src_dir)
    if exists("%s/__main__.py" % src_dir):
        os.rename("%s/__main__.py" % src_dir, "%s/main__.py" % src_dir)

    # write the boilerplate in a temp dir
    copy_replace(launcher, "%s/exec__.py" % src_dir,
          "from main__ import main as main",
          "from main__ import %s as main" % main )

# compile sources
def build(src_dir, tgt_dir):
    # in general, compile your program into an executable format
    # for scripting languages, move sources and create a launcher
    # move away the action dir and replace with the new
    shutil.rmtree(tgt_dir)
    shutil.move(src_dir, tgt_dir)
    tgt_file = "%s/exec" % tgt_dir
    write_file(tgt_file, """#!/bin/bash
export PYTHONIOENCODING=UTF-8
if [ "$(cat $0.env)" = "$__OW_EXECUTION_ENV" ]
then cd "$(dirname $0)"
     exec /usr/local/bin/python exec__.py "$@"
else echo "Execution Environment Mismatch"
     echo "Expected: $(cat $0.env)"
     echo "Actual: $__OW_EXECUTION_ENV"
     exit 1
fi
""", True)
    write_file("%s.env"%tgt_file, os.environ['__OW_EXECUTION_ENV'])
    return tgt_file

#check if a module exists
def check(tgt_dir, module_name):
    try:
        sys.path.append(tgt_dir)
        mod = importlib.util.find_spec(module_name)
        if mod:
            with open(mod.origin, "rb") as f:
                ast.parse(f.read().decode("utf-8"))
            # check virtualenv
            path_to_virtualenv = abspath('%s/virtualenv' % tgt_dir)
            if os.path.isdir(path_to_virtualenv):
                activate_this_file = path_to_virtualenv + '/bin/activate_this.py'
                if not os.path.exists(activate_this_file):
                   sys.stderr.write('Invalid virtualenv. Zip file does not include activate_this.py')
        else:
            sys.stderr.write("Zip file does not include %s" % module_name)
    except SyntaxError as er:
        sys.stderr.write(er.msg)
    except Exception as ex:
        sys.stderr.write(ex)
    sys.stderr.flush()

if __name__ == '__main__':
    if len(sys.argv) < 4:
        sys.stdout.write("usage: <main-function> <source-dir> <target-dir>\n")
        sys.stdout.flush()
        sys.exit(1)
    launcher = "%s/lib/launcher.py" % dirname(dirname(sys.argv[0]))
    src_dir = abspath(sys.argv[2])
    tgt_dir = abspath(sys.argv[3])
    sources(launcher, sys.argv[1], src_dir)
    tgt = build(abspath(sys.argv[2]), tgt_dir)
    check(tgt_dir, "main__")
    sys.stdout.flush()
    sys.stderr.flush()
