/*
 *  ======== what.rel ========
 */
var footer = xdc.loadTemplate("footer.xdt");

/* This MUST be done in this way so copyright.rel
 * does not interpret as a real start end tag inside itself
 */
var PRE_MARKER = "--";
var POST_MARKER = "--";
var COPYRIGHT_START = PRE_MARKER + "COPYRIGHT" + POST_MARKER;
var COPYRIGHT_END = PRE_MARKER + "/COPYRIGHT" + POST_MARKER;

var PRODUCT = Manifest.packageName;
var COMPANY_NAME = "Texas Instruments Incorporated";

var VERSION = Manifest.compatibilityKey; 
if (VERSION == "") {
    VERSION = "1,0,0";
}
VERSION += "," + Manifest.buildCount; 

var today = new Date();
var DATE = (today.getUTCMonth() + 1)
     + "-" + today.getUTCDate()
     + "-" + today.getFullYear();

var CPYYEAR = today.getFullYear();

/** create a buffered output stream for the destination file */
function createOutStream(name)
{
    var file = java.io.FileOutputStream(name, true);
    var buf = java.io.BufferedOutputStream(file);
    return java.io.PrintStream(buf);
}

/** copy a file verbatim to the output stream */
function copyFileToStream(out, name)
{
    var inChan = java.io.FileInputStream(name).getChannel();
    var outChan = java.nio.channels.Channels.newChannel(out);
    var pos = 0;
    while (pos < inChan.size()) {
        pos += inChan.transferTo(pos, inChan.size() - pos, outChan);
    }
    inChan.close();
}

/** expand the copyright notice and add footer */
function expandCopyright(filter, src, dst, base)
{
    var out = createOutStream(dst);
    var ins = new java.io.BufferedReader(new java.io.FileReader(src));
    var line;

    while ((line = ins.readLine()) != null) {

        /* iterate through in and read each line
         * copy each line to outs until a COPYRIGHT is found
         * if COPYRIGHT is found then read through the lines
         * in the input file until /COPYRIGHT is found replacing
         * all occurances of $(VAR) with the expasion
         */
        var lineIn = new String(line);
        if (lineIn.indexOf(COPYRIGHT_START) > -1) {
            /* Found an internal copyright. */
            processCopyright(lineIn, ins, out);
        }
        else {
            out.println(lineIn);
        }
    }
    if (ins != null) {
        ins.close(); 
    }

    footer.genStream(out, utils.global, [src, dst, base]);
    out.close();
}

/* 
 *  ======== processCopyright ========
 *  Removes the COPYRIGHT> and /COPYRIGHT tags and process
 *  each line for variable substitutions.
 */
function processCopyright(currentLine, ins, ps)
{
    /* first process the current line.  We need to remove the COPYRIGHT tag
     * but leave everything else alone
     */

    /* c_length is the length of the tag+ license type. Like COPYRIGHT,BSD
     * Continue processing until the fist white space chr.
     */
    var c_length=0;
    if  (currentLine.indexOf(COPYRIGHT_START) > -1) {
        var startIdx = currentLine.indexOf(COPYRIGHT_START);
        for (var i = startIdx;i < currentLine.length;i++) {
            c_length++;
            if (java.lang.Character.isWhitespace(currentLine.charAt(i))) {
                break;
            }
        }
    }

    /* get the chrs before the tag */
    var modLine = currentLine.substring(0,
        currentLine.indexOf(COPYRIGHT_START));

    /* and after */
    modLine = modLine + currentLine.substring(
        currentLine.indexOf(COPYRIGHT_START) + c_length);

    modLine = processLine(modLine);
    ps.println(modLine);

    while ((lineIn = ins.readLine()) != null) {
        if (lineIn.indexOf(COPYRIGHT_END) != -1) {
            /* ok, found the end so bail! Get the chrs before the tag */
            modLine = lineIn.substring(0, lineIn.indexOf(COPYRIGHT_END));
            
            /* and after the tag */
            modLine = modLine + lineIn.substring(lineIn.indexOf(COPYRIGHT_END)
                + COPYRIGHT_END.length);
            modLine = processLine(modLine);
            ps.println(modLine);
            break;
        }
        modLine = processLine(lineIn);
        ps.println(modLine);
    }
}

/*
 *  ======== processLine ========
 *  Performs variable substitution on each line.
 */
function processLine(line)
{
    /* iterate through the line and find any occurances of $(VAR) and replace
     * with the value of $(VAR)  if it exists.  If it does not, put in
     * UNDEFINED
     */
    if (line.indexOf("$(") > -1) {
        var resultString = new String();
        while (line.indexOf("$(") > -1)  {
            var startOfToken = line.indexOf("$(");
            var lineBeforeToken = line.substring(0, startOfToken);
            var token = line.substring(startOfToken + 2,
                line.indexOf(")", startOfToken + 2));
            var line = line.substring(startOfToken + 2 + token.length() + 1);
            if (resultString == "") {
                resultString = lineBeforeToken + lookupTokenValue(token);
            }
            else {
                resultString = resultString + lineBeforeToken
                    + lookupTokenValue(token);
            }
        } 
        /* return the substituted string + the rest of the line with no VARS */
        return (resultString + line);
    }

    /* No substitutions */
    return (line);
}

/* for all files in this release */
for (var i  = 0; i < Manifest.files.length; i++) {
    var fname = Manifest.files[i];

    /* skip generated files */
    if (fname.match(/\/package\//) != null
        || fname.match(/\.xdc\.[ch]$/) != null) {
        continue;
    }

    /* skip eclipse plugin.xml files */
    if (fname.match(/\/plugin\.xml/) != null) {
        continue;
    }

    /* add copyright to various source files */
    if (fname.match(/makefile|Makefile|\.([ch]|cpp|xs|xdc|xdt|tc[ip]|tcf|js|mak|pl|cfg|bld|dtd|sh|ksh|rel|xml|htm|html)$/) != null) {

        Manifest.filterMap[fname] = {
            operation: expandCopyright,
            newFileMode: "rw"
        };
    }
}
