/*
 * Copyright (c) 2002, 2003, 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.
 *
 * 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.
 *
 */

package sun.jvm.hotspot.jdi;

import com.sun.jdi.*;

import java.util.*;
import java.io.File;

class SDE {
    private static final int INIT_SIZE_FILE = 3;
    private static final int INIT_SIZE_LINE = 100;
    private static final int INIT_SIZE_STRATUM = 3;

    static final String BASE_STRATUM_NAME = "Java";

    /* for C capatibility */
    static final String NullString = null;

    private class FileTableRecord {
        int fileId;
        String sourceName;
        String sourcePath; // do not read - use accessor
        boolean isConverted = false;

        /**
         * Return the sourcePath, computing it if not set.
         * If set, convert '/' in the sourcePath to the
         * local file separator.
         */
        String getSourcePath(ReferenceTypeImpl refType) {
            if (!isConverted) {
                if (sourcePath == null) {
                    sourcePath = refType.baseSourceDir() + sourceName;
                } else {
                    StringBuffer buf = new StringBuffer();
                    for (int i = 0; i < sourcePath.length(); ++i) {
                        char ch = sourcePath.charAt(i);
                        if (ch == '/') {
                            buf.append(File.separatorChar);
                        } else {
                            buf.append(ch);
                        }
                    }
                    sourcePath = buf.toString();
                }
                isConverted = true;
            }
            return sourcePath;
        }
    }

    private class LineTableRecord {
        int jplsStart;
        int jplsEnd;
        int jplsLineInc;
        int njplsStart;
        int njplsEnd;
        int fileId;
    }

    private class StratumTableRecord {
        String id;
        int fileIndex;
        int lineIndex;
    }

    class Stratum {
        private final int sti; /* stratum index */

        private Stratum(int sti) {
            this.sti = sti;
        }

        String id() {
            return stratumTable[sti].id;
        }

        boolean isJava() {
            return sti == baseStratumIndex;
        }

        /**
         * Return all the sourceNames for this stratum.
         * Look from our starting fileIndex upto the starting
         * fileIndex of next stratum - can do this since there
         * is always a terminator stratum.
         * Default sourceName (the first one) must be first.
         */
        List sourceNames(ReferenceTypeImpl refType) {
            int i;
            int fileIndexStart = stratumTable[sti].fileIndex;
            /* one past end */
            int fileIndexEnd = stratumTable[sti+1].fileIndex;
            List result = new ArrayList(fileIndexEnd - fileIndexStart);
            for (i = fileIndexStart; i < fileIndexEnd; ++i) {
                result.add(fileTable[i].sourceName);
            }
            return result;
        }

        /**
         * Return all the sourcePaths for this stratum.
         * Look from our starting fileIndex upto the starting
         * fileIndex of next stratum - can do this since there
         * is always a terminator stratum.
         * Default sourcePath (the first one) must be first.
         */
        List sourcePaths(ReferenceTypeImpl refType) {
            int i;
            int fileIndexStart = stratumTable[sti].fileIndex;
            /* one past end */
            int fileIndexEnd = stratumTable[sti+1].fileIndex;
            List result = new ArrayList(fileIndexEnd - fileIndexStart);
            for (i = fileIndexStart; i < fileIndexEnd; ++i) {
                result.add(fileTable[i].getSourcePath(refType));
            }
            return result;
        }

        LineStratum lineStratum(ReferenceTypeImpl refType,
                                int jplsLine) {
            int lti = stiLineTableIndex(sti, jplsLine);
            if (lti < 0) {
                return null;
            } else {
                return new LineStratum(sti, lti, refType,
                                       jplsLine);
            }
        }
    }

    class LineStratum {
        private final int sti; /* stratum index */
        private final int lti; /* line table index */
        private final ReferenceTypeImpl refType;
        private final int jplsLine;
        private String sourceName = null;
        private String sourcePath = null;

        private LineStratum(int sti, int lti,
                            ReferenceTypeImpl refType,
                            int jplsLine) {
            this.sti = sti;
            this.lti = lti;
            this.refType = refType;
            this.jplsLine = jplsLine;
        }

        public boolean equals(Object obj) {
            if ((obj != null) && (obj instanceof LineStratum)) {
                LineStratum other = (LineStratum)obj;
                return (lti == other.lti) &&
                       (sti == other.sti) &&
                       (lineNumber() == other.lineNumber()) &&
                       (refType.equals(other.refType));
            } else {
                return false;
            }
        }

        int lineNumber() {
            return stiLineNumber(sti, lti, jplsLine);
        }

        /**
         * Fetch the source name and source path for
         * this line, converting or constructing
         * the source path if needed.
         */
        void getSourceInfo() {
            if (sourceName != null) {
                // already done
                return;
            }
            int fti = stiFileTableIndex(sti, lti);
            if (fti == -1) {
                throw new InternalError(
              "Bad SourceDebugExtension, no matching source id " +
              lineTable[lti].fileId + " jplsLine: " + jplsLine);
            }
            FileTableRecord ftr = fileTable[fti];
            sourceName = ftr.sourceName;
            sourcePath = ftr.getSourcePath(refType);
        }

        String sourceName() {
            getSourceInfo();
            return sourceName;
        }

        String sourcePath() {
            getSourceInfo();
            return sourcePath;
        }
    }

    private FileTableRecord[] fileTable = null;
    private LineTableRecord[] lineTable = null;
    private StratumTableRecord[] stratumTable = null;

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

    private int defaultStratumIndex = -1;
    private int baseStratumIndex = -2; /* so as not to match -1 above */
    private int sdePos = 0;

    final String sourceDebugExtension;
    String jplsFilename = null;
    String defaultStratumId = null;
    boolean isValid = false;

    SDE(String sourceDebugExtension) {
        this.sourceDebugExtension = sourceDebugExtension;
        decode();
    }

    SDE() {
        this.sourceDebugExtension = null;
        createProxyForAbsentSDE();
    }

    char sdePeek() {
        if (sdePos >= sourceDebugExtension.length()) {
            syntax();
        }
        return sourceDebugExtension.charAt(sdePos);
    }

    char sdeRead() {
        if (sdePos >= sourceDebugExtension.length()) {
            syntax();
        }
        return sourceDebugExtension.charAt(sdePos++);
    }

    void sdeAdvance() {
        sdePos++;
    }

    void syntax() {
        throw new InternalError("bad SourceDebugExtension syntax - position " +
                                sdePos);
    }

    void syntax(String msg) {
        throw new InternalError("bad SourceDebugExtension syntax: " + msg);
    }

    void assureLineTableSize() {
        int len = lineTable == null? 0 : lineTable.length;
        if (lineIndex >= len) {
            int i;
            int newLen = len == 0? INIT_SIZE_LINE : len * 2;
            LineTableRecord[] newTable = new LineTableRecord[newLen];
            for (i = 0; i < len; ++i) {
                newTable[i] = lineTable[i];
            }
            for (; i < newLen; ++i) {
                newTable[i] = new LineTableRecord();
            }
            lineTable = newTable;
        }
    }

    void assureFileTableSize() {
        int len = fileTable == null? 0 : fileTable.length;
        if (fileIndex >= len) {
            int i;
            int newLen = len == 0? INIT_SIZE_FILE : len * 2;
            FileTableRecord[] newTable = new FileTableRecord[newLen];
            for (i = 0; i < len; ++i) {
                newTable[i] = fileTable[i];
            }
            for (; i < newLen; ++i) {
                newTable[i] = new FileTableRecord();
            }
            fileTable = newTable;
        }
    }

    void assureStratumTableSize() {
        int len = stratumTable == null? 0 : stratumTable.length;
        if (stratumIndex >= len) {
            int i;
            int newLen = len == 0? INIT_SIZE_STRATUM : len * 2;
            StratumTableRecord[] newTable = new StratumTableRecord[newLen];
            for (i = 0; i < len; ++i) {
                newTable[i] = stratumTable[i];
            }
            for (; i < newLen; ++i) {
                newTable[i] = new StratumTableRecord();
            }
            stratumTable = newTable;
        }
    }

    String readLine() {
        StringBuffer sb = new StringBuffer();
        char ch;

        ignoreWhite();
        while (((ch = sdeRead()) != '\n') && (ch != '\r')) {
            sb.append((char)ch);
        }
        // check for CR LF
        if ((ch == '\r') && (sdePeek() == '\n')) {
            sdeRead();
        }
        ignoreWhite(); // leading white
        return sb.toString();
    }

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

    int stratumTableIndex(String stratumId) {
        int i;

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

    Stratum stratum(String stratumID) {
        int sti = stratumTableIndex(stratumID);
        return new Stratum(sti);
    }

    List availableStrata() {
        List strata = new ArrayList();

        for (int i = 0; i < (stratumIndex-1); ++i) {
            StratumTableRecord rec = stratumTable[i];
            strata.add(rec.id);
        }
        return strata;
    }

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

    void ignoreWhite() {
        char ch;

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

    void ignoreLine() {
        char ch;

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

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

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

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

    void fileLine() {
        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);
    }

    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
     */
    void lineLine() {
        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();
        }
        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.
     */
    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
     */
    void stratumSection() {
        storeStratum(readLine());
    }

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

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

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

    /**
     * A base "Java" stratum is always available, though
     * it is not in the SourceDebugExtension.
     * Create the base stratum.
     */
    void createJavaStratum() {
        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.
     */
    void decode() {
        /* check for "SMAP" - allow EOF if not ours */
        if ((sourceDebugExtension.length() < 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();
            }
            switch (sdeRead()) {
                case 'S':
                    stratumSection();
                    break;
                case 'F':
                    fileSection();
                    break;
                case 'L':
                    lineSection();
                    break;
                case 'E':
                    /* set end points */
                    storeStratum("*terminator*");
                    isValid = true;
                    return;
                default:
                    ignoreSection();
            }
        }
    }

    void createProxyForAbsentSDE() {
        jplsFilename = null;
        defaultStratumId = BASE_STRATUM_NAME;
        defaultStratumIndex = stratumIndex;
        createJavaStratum();
        storeStratum("*terminator*");
    }

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

    boolean isValid() {
        return isValid;
    }
}
