/*
 * Copyright 2001 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.tools.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<String> sourceNames(ReferenceTypeImpl refType) {
            int i;
            int fileIndexStart = stratumTable[sti].fileIndex;
            /* one past end */
            int fileIndexEnd = stratumTable[sti+1].fileIndex;
            List<String> result = new ArrayList<String>(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<String> sourcePaths(ReferenceTypeImpl refType) {
            int i;
            int fileIndexStart = stratumTable[sti].fileIndex;
            /* one past end */
            int fileIndexEnd = stratumTable[sti+1].fileIndex;
            List<String> result = new ArrayList<String>(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<String> availableStrata() {
        List<String> strata = new ArrayList<String>();

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