/*
 * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include <setjmp.h>

#include "util.h"
#include "SDE.h"

/**
 * This SourceDebugExtension code does not
 * allow concurrent translation - due to caching method.
 * A separate thread setting the default stratum ID
 * is, however, fine.
 */

#define INIT_SIZE_FILE 10
#define INIT_SIZE_LINE 100
#define INIT_SIZE_STRATUM 3

#define BASE_STRATUM_NAME "Java"

#define null NULL
#define true JNI_TRUE
#define false JNI_FALSE
#define String char *
#define private static

typedef struct {
  int fileId;
  String sourceName;
  String sourcePath; // do not read - use accessor
  int isConverted;
} FileTableRecord;

typedef struct {
    int jplsStart;
    int jplsEnd;
    int jplsLineInc;
    int njplsStart;
    int njplsEnd;
    int fileId;
} LineTableRecord;

typedef struct {
    String id;
    int fileIndex;
    int lineIndex;
} StratumTableRecord;

/* back-end wide value for default stratum */
private String globalDefaultStratumId = null;

/* reference type default */
private String defaultStratumId = null;

private jclass cachedClass = NULL;

private FileTableRecord* fileTable;
private LineTableRecord* lineTable;
private StratumTableRecord* stratumTable;

private int fileTableSize;
private int lineTableSize;
private int stratumTableSize;

private int fileIndex;
private int lineIndex;
private int stratumIndex = 0;
private int currentFileId;

private int defaultStratumIndex;
private int baseStratumIndex;
private char* sdePos;

private char* jplsFilename = null;
private char* NullString = null;

/* mangled in parse, cannot be parsed.  Must be kept. */
private String sourceDebugExtension;

private jboolean sourceMapIsValid;

private jmp_buf jmp_buf_env;

private int stratumTableIndex(String stratumId);
private int stiLineTableIndex(int sti, int jplsLine);
private int stiLineNumber(int sti, int lti, int jplsLine);
private void decode(void);
private void ignoreWhite(void);
private jboolean isValid(void);

    private void
    loadDebugInfo(JNIEnv *env, jclass clazz) {

        if (!isSameObject(env, clazz, cachedClass)) {
            /* Not the same - swap out the info */

            /* Delete existing info */
            if ( cachedClass != null ) {
                tossGlobalRef(env, &cachedClass);
                cachedClass = null;
            }
            if ( sourceDebugExtension!=null ) {
                jvmtiDeallocate(sourceDebugExtension);
            }
            sourceDebugExtension = null;

            /* Init info */
            lineTable = null;
            fileTable = null;
            stratumTable = null;
            lineTableSize = 0;
            fileTableSize = 0;
            stratumTableSize = 0;
            fileIndex = 0;
            lineIndex = 0;
            stratumIndex = 0;
            currentFileId = 0;
            defaultStratumId = null;
            defaultStratumIndex = -1;
            baseStratumIndex = -2; /* so as not to match -1 above */
            sourceMapIsValid = false;

            if (getSourceDebugExtension(clazz, &sourceDebugExtension) ==
                JVMTI_ERROR_NONE) {
                sdePos = sourceDebugExtension;
                if (setjmp(jmp_buf_env) == 0) {
                    /* this is the initial (non-error) case, do parse */
                    decode();
                }
            }

            cachedClass = null;
            saveGlobalRef(env, clazz, &cachedClass);
        }
    }

    /* Return 1 if match, 0 if no match */
    private int
    patternMatch(char *classname, const char *pattern) {
        int pattLen;
        int compLen;
        char *start;
        int offset;

        if (pattern == NULL || classname == NULL) {
            return 0;
        }
        pattLen = (int)strlen(pattern);

        if ((pattern[0] != '*') && (pattern[pattLen-1] != '*')) {
            return strcmp(pattern, classname) == 0;
        }

        compLen = pattLen - 1;
        offset = (int)strlen(classname) - compLen;
        if (offset < 0) {
            return 0;
        }
        if (pattern[0] == '*') {
            pattern++;
            start = classname + offset;
        }  else {
            start = classname;
        }
        return strncmp(pattern, start, compLen) == 0;
    }

    /**
     * Return 1 if p1 is a SourceName for stratum sti,
     * else, return 0.
     */
    private int
    searchOneSourceName(int sti, char *p1) {
        int fileIndexStart = stratumTable[sti].fileIndex;
        /* one past end */
        int fileIndexEnd = stratumTable[sti+1].fileIndex;
        int ii;
        for (ii = fileIndexStart; ii < fileIndexEnd; ++ii) {
            if (patternMatch(fileTable[ii].sourceName, p1)) {
              return 1;
            }
        }
        return 0;
    }

    /**
     * Return 1 if p1 is a SourceName for any stratum
     * else, return 0.
     */
    int searchAllSourceNames(JNIEnv *env,
                             jclass clazz,
                             char *p1) {
        int ii;
        loadDebugInfo(env, clazz);
        if (!isValid()) {
          return 0; /* no SDE or not SourceMap */
        }

        for (ii = 0; ii < stratumIndex - 1; ++ii) {
            if (searchOneSourceName(ii, p1) == 1) {
                return 1;
            }
        }
        return 0;
    }

    /**
     * Convert a line number table, as returned by the JVMTI
     * function GetLineNumberTable, to one for another stratum.
     * Conversion is by overwrite.
     * Actual line numbers are not returned - just a unique
     * number (file ID in top 16 bits, line number in
     * bottom 16 bits) - this is all stepping needs.
     */
    void
    convertLineNumberTable(JNIEnv *env, jclass clazz,
                           jint *entryCountPtr,
                           jvmtiLineNumberEntry **tablePtr) {
        jvmtiLineNumberEntry *fromEntry = *tablePtr;
        jvmtiLineNumberEntry *toEntry = *tablePtr;
        int cnt = *entryCountPtr;
        int lastLn = 0;
        int sti;

        loadDebugInfo(env, clazz);
        if (!isValid()) {
            return; /* no SDE or not SourceMap - return unchanged */
        }
        sti = stratumTableIndex(globalDefaultStratumId);
        if (sti == baseStratumIndex) {
            return; /* Java stratum - return unchanged */
        }
        LOG_MISC(("SDE is re-ordering the line table"));
        for (; cnt-->0; ++fromEntry) {
            int jplsLine = fromEntry->line_number;
            int lti = stiLineTableIndex(sti, jplsLine);
            if (lti >= 0) {
                int fileId = lineTable[lti].fileId;
                int ln = stiLineNumber(sti, lti, jplsLine);
                ln += (fileId << 16); /* create line hash */
                if (ln != lastLn) {
                    lastLn = ln;
                    toEntry->start_location = fromEntry->start_location;
                    toEntry->line_number = ln;
                    ++toEntry;
                }
            }
        }
        /*LINTED*/
        *entryCountPtr = (int)(toEntry - *tablePtr);
    }

    /**
     * Set back-end wide default stratum ID .
     */
    void
    setGlobalStratumId(char *id) {
        globalDefaultStratumId = id;
    }


    private void syntax(String msg) {
        char buf[200];
        (void)snprintf(buf, sizeof(buf),
                "bad SourceDebugExtension syntax - position %d - %s\n",
                /*LINTED*/
                (int)(sdePos-sourceDebugExtension),
                msg);
        JDI_ASSERT_FAILED(buf);

        longjmp(jmp_buf_env, 1);  /* abort parse */
    }

    private char sdePeek(void) {
        if (*sdePos == 0) {
            syntax("unexpected EOF");
        }
        return *sdePos;
    }

    private char sdeRead(void) {
        if (*sdePos == 0) {
            syntax("unexpected EOF");
        }
        return *sdePos++;
    }

    private void sdeAdvance(void) {
        sdePos++;
    }

    private void assureLineTableSize(void) {
        if (lineIndex >= lineTableSize) {
            size_t allocSize;
            LineTableRecord* new_lineTable;
            int new_lineTableSize;

            new_lineTableSize = lineTableSize == 0?
                                  INIT_SIZE_LINE :
                                  lineTableSize * 2;
            allocSize = new_lineTableSize * (int)sizeof(LineTableRecord);
            new_lineTable = jvmtiAllocate((jint)allocSize);
            if ( new_lineTable == NULL ) {
                EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE line table");
            }
            if ( lineTable!=NULL ) {
                (void)memcpy(new_lineTable, lineTable,
                        lineTableSize * (int)sizeof(LineTableRecord));
                jvmtiDeallocate(lineTable);
            }
            lineTable     = new_lineTable;
            lineTableSize = new_lineTableSize;
        }
    }

    private void assureFileTableSize(void) {
        if (fileIndex >= fileTableSize) {
            size_t allocSize;
            FileTableRecord* new_fileTable;
            int new_fileTableSize;

            new_fileTableSize = fileTableSize == 0?
                                  INIT_SIZE_FILE :
                                  fileTableSize * 2;
            allocSize = new_fileTableSize * (int)sizeof(FileTableRecord);
            new_fileTable = jvmtiAllocate((jint)allocSize);
            if ( new_fileTable == NULL ) {
                EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE file table");
            }
            if ( fileTable!=NULL ) {
                (void)memcpy(new_fileTable, fileTable,
                        fileTableSize * (int)sizeof(FileTableRecord));
                jvmtiDeallocate(fileTable);
            }
            fileTable     = new_fileTable;
            fileTableSize = new_fileTableSize;
        }
    }

    private void assureStratumTableSize(void) {
        if (stratumIndex >= stratumTableSize) {
            size_t allocSize;
            StratumTableRecord* new_stratumTable;
            int new_stratumTableSize;

            new_stratumTableSize = stratumTableSize == 0?
                                  INIT_SIZE_STRATUM :
                                  stratumTableSize * 2;
            allocSize = new_stratumTableSize * (int)sizeof(StratumTableRecord);
            new_stratumTable = jvmtiAllocate((jint)allocSize);
            if ( new_stratumTable == NULL ) {
                EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE stratum table");
            }
            if ( stratumTable!=NULL ) {
                (void)memcpy(new_stratumTable, stratumTable,
                        stratumTableSize * (int)sizeof(StratumTableRecord));
                jvmtiDeallocate(stratumTable);
            }
            stratumTable     = new_stratumTable;
            stratumTableSize = new_stratumTableSize;
        }
    }

    private String readLine(void) {
        char *initialPos;
        char ch;

        ignoreWhite();
        initialPos = sdePos;
        while (((ch = *sdePos) != '\n') && (ch != '\r')) {
            if (ch == 0) {
                syntax("unexpected EOF");
            }
            ++sdePos;
        }
        *sdePos++ = 0; /* null terminate string - mangles SDE */

        /* check for CR LF */
        if ((ch == '\r') && (*sdePos == '\n')) {
            ++sdePos;
        }
        ignoreWhite(); /* leading white */
        return initialPos;
    }

    private int defaultStratumTableIndex(void) {
        if ((defaultStratumIndex == -1) && (defaultStratumId != null)) {
            defaultStratumIndex =
                stratumTableIndex(defaultStratumId);
        }
        return defaultStratumIndex;
    }

    private int stratumTableIndex(String stratumId) {
        int i;

        if (stratumId == null) {
            return defaultStratumTableIndex();
        }
        for (i = 0; i < (stratumIndex-1); ++i) {
            if (strcmp(stratumTable[i].id, stratumId) == 0) {
                return i;
            }
        }
        return defaultStratumTableIndex();
    }


/*****************************
 * below functions/methods are written to compile under either Java or C
 *
 * Needed support functions:
 *   sdePeek()
 *   sdeRead()
 *   sdeAdvance()
 *   readLine()
 *   assureLineTableSize()
 *   assureFileTableSize()
 *   assureStratumTableSize()
 *   syntax(String)
 *
 *   stratumTableIndex(String)
 *
 * Needed support variables:
 *   lineTable
 *   lineIndex
 *   fileTable
 *   fileIndex
 *   currentFileId
 *
 * Needed types:
 *   String
 *
 * Needed constants:
 *   NullString
 */

    private void ignoreWhite(void) {
        char ch;

        while (((ch = sdePeek()) == ' ') || (ch == '\t')) {
            sdeAdvance();
        }
    }

    private void ignoreLine(void) {
        char ch;

        do {
           ch = sdeRead();
        } while ((ch != '\n') && (ch != '\r'));

        /* check for CR LF */
        if ((ch == '\r') && (sdePeek() == '\n')) {
            sdeAdvance();
        }
        ignoreWhite(); /* leading white */
    }

    private int readNumber(void) {
        int value = 0;
        char ch;

        ignoreWhite();
        while (((ch = sdePeek()) >= '0') && (ch <= '9')) {
            sdeAdvance();
            value = (value * 10) + ch - '0';
        }
        ignoreWhite();
        return value;
    }

    private void storeFile(int fileId, String sourceName, String sourcePath) {
        assureFileTableSize();
        fileTable[fileIndex].fileId = fileId;
        fileTable[fileIndex].sourceName = sourceName;
        fileTable[fileIndex].sourcePath = sourcePath;
        ++fileIndex;
    }

    private void fileLine(void) {
        int hasAbsolute = 0; /* acts as boolean */
        int fileId;
        String sourceName;
        String sourcePath = null;

        /* is there an absolute filename? */
        if (sdePeek() == '+') {
            sdeAdvance();
            hasAbsolute = 1;
        }
        fileId = readNumber();
        sourceName = readLine();
        if (hasAbsolute == 1) {
            sourcePath = readLine();
        }
        storeFile(fileId, sourceName, sourcePath);
    }

    private void storeLine(int jplsStart, int jplsEnd, int jplsLineInc,
                  int njplsStart, int njplsEnd, int fileId) {
        assureLineTableSize();
        lineTable[lineIndex].jplsStart = jplsStart;
        lineTable[lineIndex].jplsEnd = jplsEnd;
        lineTable[lineIndex].jplsLineInc = jplsLineInc;
        lineTable[lineIndex].njplsStart = njplsStart;
        lineTable[lineIndex].njplsEnd = njplsEnd;
        lineTable[lineIndex].fileId = fileId;
        ++lineIndex;
    }

    /**
     * Parse line translation info.  Syntax is
     *     <NJ-start-line> [ # <file-id> ] [ , <line-count> ] :
     *                 <J-start-line> [ , <line-increment> ] CR
     */
    private void lineLine(void) {
        int lineCount = 1;
        int lineIncrement = 1;
        int njplsStart;
        int jplsStart;

        njplsStart = readNumber();

        /* is there a fileID? */
        if (sdePeek() == '#') {
            sdeAdvance();
            currentFileId = readNumber();
        }

        /* is there a line count? */
        if (sdePeek() == ',') {
            sdeAdvance();
            lineCount = readNumber();
        }

        if (sdeRead() != ':') {
            syntax("expected ':'");
        }
        jplsStart = readNumber();
        if (sdePeek() == ',') {
            sdeAdvance();
            lineIncrement = readNumber();
        }
        ignoreLine(); /* flush the rest */

        storeLine(jplsStart,
                  jplsStart + (lineCount * lineIncrement) -1,
                  lineIncrement,
                  njplsStart,
                  njplsStart + lineCount -1,
                  currentFileId);
    }

    /**
     * Until the next stratum section, everything after this
     * is in stratumId - so, store the current indicies.
     */
    private void storeStratum(String stratumId) {
        /* remove redundant strata */
        if (stratumIndex > 0) {
            if ((stratumTable[stratumIndex-1].fileIndex
                                            == fileIndex) &&
                (stratumTable[stratumIndex-1].lineIndex
                                            == lineIndex)) {
                /* nothing changed overwrite it */
                --stratumIndex;
            }
        }
        /* store the results */
        assureStratumTableSize();
        stratumTable[stratumIndex].id = stratumId;
        stratumTable[stratumIndex].fileIndex = fileIndex;
        stratumTable[stratumIndex].lineIndex = lineIndex;
        ++stratumIndex;
        currentFileId = 0;
    }

    /**
     * The beginning of a stratum's info
     */
    private void stratumSection(void) {
        storeStratum(readLine());
    }

    private void fileSection(void) {
        ignoreLine();
        while (sdePeek() != '*') {
            fileLine();
        }
    }

    private void lineSection(void) {
        ignoreLine();
        while (sdePeek() != '*') {
            lineLine();
        }
    }

    /**
     * Ignore a section we don't know about.
     */
    private void ignoreSection(void) {
        ignoreLine();
        while (sdePeek() != '*') {
            ignoreLine();
        }
    }

    /**
     * A base "Java" stratum is always available, though
     * it is not in the SourceDebugExtension.
     * Create the base stratum.
     */
    private void createJavaStratum(void) {
        baseStratumIndex = stratumIndex;
        storeStratum(BASE_STRATUM_NAME);
        storeFile(1, jplsFilename, NullString);
        /* JPL line numbers cannot exceed 65535 */
        storeLine(1, 65536, 1, 1, 65536, 1);
        storeStratum("Aux"); /* in case they don't declare */
    }

    /**
     * Decode a SourceDebugExtension which is in SourceMap format.
     * This is the entry point into the recursive descent parser.
     */
    private void decode(void) {
        /* check for "SMAP" - allow EOF if not ours */
        if (strlen(sourceDebugExtension) <= 4 ||
            (sdeRead() != 'S') ||
            (sdeRead() != 'M') ||
            (sdeRead() != 'A') ||
            (sdeRead() != 'P')) {
            return; /* not our info */
        }
        ignoreLine(); /* flush the rest */
        jplsFilename = readLine();
        defaultStratumId = readLine();
        createJavaStratum();
        while (true) {
            if (sdeRead() != '*') {
                syntax("expected '*'");
            }
            switch (sdeRead()) {
                case 'S':
                    stratumSection();
                    break;
                case 'F':
                    fileSection();
                    break;
                case 'L':
                    lineSection();
                    break;
                case 'E':
                    /* set end points */
                    storeStratum("*terminator*");
                    sourceMapIsValid = true;
                    return;
                default:
                    ignoreSection();
            }
        }
    }

    /***************** query functions ***********************/

    private int stiLineTableIndex(int sti, int jplsLine) {
        int i;
        int lineIndexStart;
        int lineIndexEnd;

        lineIndexStart = stratumTable[sti].lineIndex;
        /* one past end */
        lineIndexEnd = stratumTable[sti+1].lineIndex;
        for (i = lineIndexStart; i < lineIndexEnd; ++i) {
            if ((jplsLine >= lineTable[i].jplsStart) &&
                            (jplsLine <= lineTable[i].jplsEnd)) {
                return i;
            }
        }
        return -1;
    }

    private int stiLineNumber(int sti, int lti, int jplsLine) {
        return lineTable[lti].njplsStart +
                (((jplsLine - lineTable[lti].jplsStart) /
                                   lineTable[lti].jplsLineInc));
    }

    private int fileTableIndex(int sti, int fileId) {
        int i;
        int fileIndexStart = stratumTable[sti].fileIndex;
        /* one past end */
        int fileIndexEnd = stratumTable[sti+1].fileIndex;
        for (i = fileIndexStart; i < fileIndexEnd; ++i) {
            if (fileTable[i].fileId == fileId) {
                return i;
            }
        }
        return -1;
    }

    private int stiFileTableIndex(int sti, int lti) {
        return fileTableIndex(sti, lineTable[lti].fileId);
    }

    private jboolean isValid(void) {
        return sourceMapIsValid;
    }
