/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package org.codehaus.groovy.antlr;

import java.io.IOException;
import java.io.Reader;

import antlr.CharScanner;
import antlr.Token;
import antlr.TokenStreamException;

/**
 * Translates GLS-defined unicode escapes into characters. Throws an exception
 * in the event of an invalid unicode escape being detected.
 * <p>
 * No attempt has been made to optimize this class for speed or space.
 */
public class UnicodeEscapingReader extends Reader {

    private final Reader reader;
    private CharScanner lexer;
    private boolean hasNextChar = false;
    private int nextChar;
    private final SourceBuffer sourceBuffer;
    private int previousLine;
    private int numUnicodeEscapesFound = 0;
    private int numUnicodeEscapesFoundOnCurrentLine = 0;

    private static class DummyLexer extends CharScanner {
        private final Token t = new Token();
        public Token nextToken() throws TokenStreamException {
            return t;
        }
        @Override
        public int getColumn() {
            return 0;
        }
        @Override
        public int getLine() {
            return 0;
        }
    }
    
    /**
     * Constructor.
     * @param reader The reader that this reader will filter over.
     */
    public UnicodeEscapingReader(Reader reader,SourceBuffer sourceBuffer) {
        this.reader = reader;
        this.sourceBuffer = sourceBuffer;
        this.lexer = new DummyLexer();
    }

    /**
     * Sets the lexer that is using this reader. Must be called before the
     * lexer is used.
     */
    public void setLexer(CharScanner lexer) {
        this.lexer = lexer;
    }

    /**
     * Reads characters from the underlying reader.
     * @see java.io.Reader#read(char[],int,int)
     */
    public int read(char cbuf[], int off, int len) throws IOException {
        int c = 0;
        int count = 0;
        while (count < len && (c = read())!= -1) {
            cbuf[off + count] = (char) c;
            count++;
        }
        return (count == 0 && c == -1) ? -1 : count;
    }

    /**
     * Gets the next character from the underlying reader,
     * translating escapes as required.
     * @see java.io.Reader#close()
     */
    public int read() throws IOException {
        if (hasNextChar) {
            hasNextChar = false;
            write(nextChar);
            return nextChar;
        }

        if (previousLine != lexer.getLine()) {
            // new line, so reset unicode escapes
            numUnicodeEscapesFoundOnCurrentLine = 0;
            previousLine = lexer.getLine();
        }
        
        int c = reader.read();
        if (c != '\\') {
            write(c);
            return c;
        }

        // Have one backslash, continue if next char is 'u'
        c = reader.read();
        if (c != 'u') {
            hasNextChar = true;
            nextChar = c;
            write('\\');
            return '\\';
        }

        // Swallow multiple 'u's
        int numberOfUChars = 0;
        do {
            numberOfUChars++;
            c = reader.read();
        } while (c == 'u');

        // Get first hex digit
        checkHexDigit(c);
        StringBuilder charNum = new StringBuilder();
        charNum.append((char) c);

        // Must now be three more hex digits
        for (int i = 0; i < 3; i++) {
            c = reader.read();
            checkHexDigit(c);
            charNum.append((char) c);
        }
        int rv = Integer.parseInt(charNum.toString(), 16);
        write(rv);
        
        numUnicodeEscapesFound += 4 + numberOfUChars;
        numUnicodeEscapesFoundOnCurrentLine += 4 + numberOfUChars;

        return rv;
    }
    private void write(int c) {
        if (sourceBuffer != null) {sourceBuffer.write(c);}
    }
    /**
     * Checks that the given character is indeed a hex digit.
     */
    private void checkHexDigit(int c) throws IOException {
        if (c >= '0' && c <= '9') {
            return;
        }
        if (c >= 'a' && c <= 'f') {
            return;
        }
        if (c >= 'A' && c <= 'F') {
            return;
        }
        // Causes the invalid escape to be skipped
        hasNextChar = true;
        nextChar = c;
        throw new IOException("Did not find four digit hex character code."
                + " line: " + lexer.getLine() + " col:" + lexer.getColumn());
    }

    public int getUnescapedUnicodeColumnCount() {
        return numUnicodeEscapesFoundOnCurrentLine;
    }

    public int getUnescapedUnicodeOffsetCount() {
        return numUnicodeEscapesFound;
    }

    /**
     * Closes this reader by calling close on the underlying reader.
     *
     * @see java.io.Reader#close()
     */
    public void close() throws IOException {
        reader.close();
    }
}
