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

# build virtualenv if there is a requirements.txt
def virtualenv(tgt_dir):
    # check virtualenv
    virtualenv_dir = abspath('%s/virtualenv' % tgt_dir)
    requirements_txt = abspath("%s/requirements.txt" % tgt_dir)
    if exists(requirements_txt):
        if not os.path.isdir(virtualenv_dir):
            cmd = "python -m virtualenv %s >/tmp/err 2>/tmp/err" % virtualenv_dir
            if os.system(cmd) != 0:
                with open("/tmp/err", "r") as f:
                    sys.stderr.write(f.read())
            else:
                cmd = ". %s/bin/activate && python -m pip install -r %s >/tmp/err 2>/tmp/err" % (virtualenv_dir, requirements_txt)
                if os.system(cmd) != 0:
                    with open("/tmp/err", "r") as f:
                        sys.stderr.write(f.read())
    sys.stderr.flush()

# 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 [[ "$__OW_EXECUTION_ENV" == "" || "$(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)
    if os.environ.get("__OW_EXECUTION_ENV"):
      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):
    # activate virtualenv if any
    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):
            # check if this was packaged for windows
            activate_this_file = path_to_virtualenv + '/Scripts/activate_this.py'
        if os.path.exists(activate_this_file):
            with open(activate_this_file) as f:
                code = compile(f.read(), activate_this_file, 'exec')
                exec(code, dict(__file__=activate_this_file))
        else:
            sys.stderr.write("Invalid virtualenv. Zip file does not include 'activate_this.py'.\n")
    # check module
    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"))
        else:
            sys.stderr.write("Zip file does not include %s\n" % 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)
    build(abspath(sys.argv[2]), tgt_dir)
    virtualenv(tgt_dir)
    check(tgt_dir, "main__")
    sys.stdout.flush()
    sys.stderr.flush()
