#!/usr/bin/env python

# ---
# 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.
# ---

import os
import re
import sys
import json
import optparse

#--------------------------------------------------------------------
def main():

    #----------------------------------------------------------------
    if len(sys.argv) < 3:
        error("expecting parameters srcDir outputDir")

    srcDirName  = sys.argv[1]
    oDirName    = sys.argv[2]

    if not os.path.exists(srcDirName):  error("source directory not found: '" + srcDirName + "'")
    if not os.path.isdir(srcDirName):   error("source directory not a directory: '" + srcDirName + "'")
    if not os.path.exists(oDirName):    error("output directory not found: '" + oDirName + "'")
    if not os.path.isdir(oDirName):     error("output directory not a directory: '" + oDirName + "'")

    #----------------------------------------------------------------
    scripts     = []
    scriptNames = {}
    scriptSrc   = {}
    scriptMin   = {}

    includedFiles = []
    includedFiles.append("modjewel-require.js")

    entries = os.listdir(os.path.join(srcDirName, "weinre/common"))
    for entry in entries:
        includedFiles.append("weinre/common/%s" % entry)

    entries = os.listdir(os.path.join(srcDirName, "weinre/target"))
    for entry in entries:
        includedFiles.append("weinre/target/%s" % entry)

    includedFiles.append("interfaces/all-json-idls-min.js")

    for includedFile in includedFiles:
        baseScriptFile = includedFile
        scriptFile = os.path.join(srcDirName, baseScriptFile)
        if not os.path.exists(scriptFile):
            error("script file not found: '" + scriptFile + "'")

        scripts.append(scriptFile)
        scriptNames[scriptFile] = baseScriptFile

        with open(scriptFile, "r") as iFile:
            scriptSrc[scriptFile] = iFile.read()

        scriptMin[scriptFile] = min(scriptSrc[scriptFile])

        # log("read: %s" % scriptFile)

    #----------------------------------------------------------------
    oFileName = os.path.join(oDirName, "target-script.js")
    writeMergedFile(oFileName, scripts, scriptNames, scriptSrc, True)

    #----------------------------------------------------------------
    oFileName = os.path.join(oDirName, "target-script-min.js")
    writeMergedFile(oFileName, scripts, scriptNames, scriptMin, False)

#--------------------------------------------------------------------
def writeMergedFile(oFileName, scripts, scriptNames, srcs, useEval):
    lines = []
    lines.append(";(function(){")

    for script in scripts:

        src     = srcs[script]
        srcName = scriptNames[script]
        if not useEval:
            lines.append("// %s" % srcName)
            lines.append(src)
            lines.append(";")
        else:
            src = "%s\n//@ sourceURL=%s" % (src, srcName)
            lines.append(";eval(%s)" % json.dumps(src))

        if srcName == "modjewel-require.js":
            lines.append("require('modjewel').warnOnRecursiveRequire(true);")
            if not useEval:
                lines.append("")

    lines.append("// require('weinre/common/Weinre').showNotImplemented();")
    lines.append("require('weinre/target/Target').main()")
    lines.append("})();")
    targetScript = "\n".join(lines)

    with open(oFileName, "w") as oFile:
        oFile.write(targetScript)

    log("generated: %s" % oFileName)

#--------------------------------------------------------------------
def min(script):
    patternCommentC   = re.compile(r"/\*.*?\*/",     re.MULTILINE + re.DOTALL)
    patternCommentCPP = re.compile(r"(?<!\\)//.*?$", re.MULTILINE)
    patternIndent     = re.compile(r"^\s*",          re.MULTILINE)
    patternBlankLine  = re.compile(r"^\s*\n",        re.MULTILINE)

    script = patternCommentC.sub(   "", script)
    script = patternCommentCPP.sub( "", script)
    script = patternIndent.sub(     "", script)
    script = patternBlankLine.sub(  "", script)

    return script

#--------------------------------------------------------------------
def log(message):
    message = "%s: %s" % (PROGRAM_NAME, message)
    print >>sys.stderr, message

#--------------------------------------------------------------------
def error(message):
    log(message)
    sys.exit(-1)

#--------------------------------------------------------------------
PROGRAM_NAME = os.path.basename(sys.argv[0])

main()
