#!/usr/bin/env python
"""Java 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
from os.path import abspath, exists, dirname
import os, sys, codecs, subprocess, shutil, logging

def copy(src, dst):
    with codecs.open(src, 'r', 'utf-8') as s:
        body = s.read()
        with codecs.open(dst, 'w', 'utf-8') as d:
            d.write(body)

def find_with_ext(basedir, ext):
    result = []
    for root, _, files in os.walk(basedir, topdown=False):
        for name in files:
            if name.endswith(ext):
                result.append(os.path.join(root,name))
    return result

def javac(sources, classpath, target_dir):
    cmd = [ "javac", 
            "-encoding", "UTF-8",
            "-cp", ":".join(classpath),
            "-d", target_dir
    ]+sources
    #print(cmd)
    logging.info(" ".join(cmd))
    p = subprocess.Popen(cmd,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    (o, e) = p.communicate()
    if isinstance(o, bytes) and not isinstance(o, str):
        o = o.decode('utf-8')
    if isinstance(e, bytes) and not isinstance(e, str):
        e = e.decode('utf-8')
    ok = True
    if o:
        ok = False
        sys.stdout.write(o)
        sys.stdout.flush()
    if e:
        ok = False
        sys.stderr.write(e)
        sys.stderr.flush()
    return ok

def build(source_dir, classpath, target_dir, mainClass):
 
    # copy exec to <main>.java if it is there
    src = "%s/exec" % source_dir
    if os.path.isfile(src):
        main_java = "%s/%s.java" % (source_dir, mainClass.split(".")[-1])
        copy(src,main_java)
        logging.info("renamed exec to %s", main_java)

    # look for sources and compile
    sources = find_with_ext(source_dir, ".java")
    if len(sources) > 0:
        jars = find_with_ext(source_dir, ".jar")
        logging.info("compiling  %d sources with %d jars", len(sources),len(jars))
        return javac(sources, classpath+jars, source_dir)
    
    return True 

def write_exec(target_dir, classpath, main):
    launcher = "%s/exec" % target_dir
    jars = find_with_ext(target_dir, ".jar")
    jars.append(target_dir)
    cmd = """#!/bin/bash
cd "%s"
/opt/java/openjdk/bin/java -Dfile.encoding=UTF-8 -cp "%s" Launcher "%s" "$@"
""" %( target_dir, ":".join(classpath+jars), main)
    with codecs.open(launcher, 'w', 'utf-8') as d:
        d.write(cmd)
    os.chmod(launcher, 0o755)

def parseMain(main):
    if main == "main":
        return "Main", "main"
    a = main.split("#")
    if(len(a)==1):
        return a[0], "main"
    return a[0], a[1]

def assemble(argv):
    mainClass, mainMethod = parseMain(argv[1])
    logging.info("%s %s", mainClass, mainMethod)
    source_dir = os.path.abspath(argv[2])
    target_dir = os.path.abspath(argv[3])
    classpath = ["/usr/java/lib/launcher.jar", "/usr/java/lib/gson-2.8.5.jar"]

    # build   
    if build(source_dir, classpath, target_dir, mainClass):
        shutil.rmtree(target_dir)
        shutil.move(source_dir, target_dir)
        logging.info("moved %s to %s", source_dir, target_dir)
        # write the launcher is it is there
        write_exec(target_dir, classpath, "%s#%s" % (mainClass, mainMethod))
        # launch it to check it can load with immediate exit - it should not produce any output
        subprocess.call(["%s/exec" % target_dir, "-exit"])
    
    sys.stdout.flush()
    sys.stderr.flush()
    
if __name__ == '__main__':
    if len(sys.argv) < 4:
        sys.stdout.write("usage: <main-class> <source-dir> <target-dir>\n")
        sys.exit(1)
    logging.basicConfig(filename="/var/log/compile.log")
    assemble(sys.argv)
