/*
 * Copyright (c) 2001, 2013, 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"

#ifdef __APPLE__
/* use setjmp/longjmp versions that do not save/restore the signal mask */
#define setjmp _setjmp
#define longjmp _longjmp
#endif

/**
 * 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;
    }
