/*
 [The "BSD license"]
 Copyright (c) 2005-2009 Terence Parr
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
 3. The name of the author may not be used to endorse or promote products
     derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.antlr.runtime;

import java.io.IOException;
import java.io.FileInputStream;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.util.List;
import java.util.ArrayList;

public class SerializedGrammar {
    public static final String COOKIE = "$ANTLR";
    public static final int FORMAT_VERSION = 1;
    //public static org.antlr.tool.Grammar gr; // TESTING ONLY; remove later

    public String name;
    public char type; // in {l, p, t, c}
    public List rules;

    class Rule {
        String name;
        Block block;
        public Rule(String name, Block block) {
            this.name = name;
            this.block = block;
        }
        public String toString() {
            return name+":"+block;
        }
    }

    class Block {
        List[] alts;
        public Block(List[] alts) {
            this.alts = alts;
        }
        public String toString() {
            StringBuffer buf = new StringBuffer();
            buf.append("(");
            for (int i = 0; i < alts.length; i++) {
                List alt = alts[i];
                if ( i>0 ) buf.append("|");
                buf.append(alt.toString());
            }
            buf.append(")");
            return buf.toString();
        }
    }

    class TokenRef {
        int ttype;
        public TokenRef(int ttype) { this.ttype = ttype; }
        public String toString() { return String.valueOf(ttype); }
    }

    class RuleRef {
        int ruleIndex;
        public RuleRef(int ruleIndex) { this.ruleIndex = ruleIndex; }
        public String toString() { return String.valueOf(ruleIndex); }
    }

    public SerializedGrammar(String filename) throws IOException {
        System.out.println("loading "+filename);
        FileInputStream fis = new FileInputStream(filename);
        BufferedInputStream bos = new BufferedInputStream(fis);
        DataInputStream in = new DataInputStream(bos);
        readFile(in);
        in.close();
    }

    protected void readFile(DataInputStream in) throws IOException {
        String cookie = readString(in); // get $ANTLR
        if ( !cookie.equals(COOKIE) ) throw new IOException("not a serialized grammar file");
        int version = in.readByte();
        char grammarType = (char)in.readByte();
        this.type = grammarType;
        String grammarName = readString(in);
        this.name = grammarName;
        System.out.println(grammarType+" grammar "+grammarName);
        int numRules = in.readShort();
        System.out.println("num rules = "+numRules);
        rules = readRules(in, numRules);
    }

    protected List readRules(DataInputStream in, int numRules) throws IOException {
        List rules = new ArrayList();
        for (int i=0; i<numRules; i++) {
            Rule r = readRule(in);
            rules.add(r);
        }
        return rules;
    }

    protected Rule readRule(DataInputStream in) throws IOException {
        byte R = in.readByte();
        if ( R!='R' ) throw new IOException("missing R on start of rule");
        String name = readString(in);
        System.out.println("rule: "+name);
        byte B = in.readByte();
        Block b = readBlock(in);
        byte period = in.readByte();
        if ( period!='.' ) throw new IOException("missing . on end of rule");
        return new Rule(name, b);
    }

    protected Block readBlock(DataInputStream in) throws IOException {
        int nalts = in.readShort();
        List[] alts = new List[nalts];
        //System.out.println("enter block n="+nalts);
        for (int i=0; i<nalts; i++) {
            List alt = readAlt(in);
            alts[i] = alt;
        }
        //System.out.println("exit block");
        return new Block(alts);
    }

    protected List readAlt(DataInputStream in) throws IOException {
        List alt = new ArrayList();
        byte A = in.readByte();
        if ( A!='A' ) throw new IOException("missing A on start of alt");
        byte cmd = in.readByte();
        while ( cmd!=';' ) {
            switch (cmd) {
                case 't' :
                    int ttype = in.readShort();
                    alt.add(new TokenRef(ttype));
                    //System.out.println("read token "+gr.getTokenDisplayName(ttype));
                    break;
                case 'r' :
                    int ruleIndex = in.readShort();
                    alt.add(new RuleRef(ruleIndex));
                    //System.out.println("read rule "+gr.getRuleName(ruleIndex));
                    break;
                case '.' : // wildcard
                    break;
                case '-' : // range
                    int from = in.readChar();
                    int to = in.readChar();
                    break;
                case '~' : // not
                    int notThisTokenType = in.readShort();
                    break;
                case 'B' : // nested block
                    Block b = readBlock(in);
                    alt.add(b);
                    break;
            }
            cmd = in.readByte();
        }
        //System.out.println("exit alt");
        return alt;
    }

    protected String readString(DataInputStream in) throws IOException {
        byte c = in.readByte();
        StringBuffer buf = new StringBuffer();
        while ( c!=';' ) {
            buf.append((char)c);
            c = in.readByte();
        }
        return buf.toString();
    }

    public String toString() {
        StringBuffer buf = new StringBuffer();
        buf.append(type+" grammar "+name);
        buf.append(rules);
        return buf.toString();
    }
}
