/*
 * 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.netbeans.modules.java.hints.declarative;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.netbeans.api.lexer.Token;
import org.netbeans.spi.lexer.Lexer;
import org.netbeans.spi.lexer.LexerInput;
import org.netbeans.spi.lexer.LexerRestartInfo;
import org.netbeans.spi.lexer.TokenFactory;

/**
 *
 * @author Jan Lahoda
 */
class DeclarativeHintLexer implements Lexer<DeclarativeHintTokenId> {

    private final LexerInput input;
    private final TokenFactory<DeclarativeHintTokenId> fact;

    public DeclarativeHintLexer(LexerRestartInfo<DeclarativeHintTokenId> info) {
        input = info.input();
        fact  = info.tokenFactory();
    }

    public Token<DeclarativeHintTokenId> nextToken() {
        int read = input.read();

        if (read == LexerInput.EOF) {
            return null;
        }

        int whitespaceLength = 0;
        
        if (Character.isWhitespace(read)) {
            while ((read != LexerInput.EOF) && Character.isWhitespace((char) read)) {
                read = input.read();
            }

            if (read == LexerInput.EOF) {
                return fact.createToken(DeclarativeHintTokenId.WHITESPACE);
            }

            whitespaceLength = input.readLength() - 1;
        }

        while (read != LexerInput.EOF) {
            Matcher variableMatcher = VARIABLE_RE.matcher(input.readText());

            if (variableMatcher.find()) {
                int start = variableMatcher.start();

                if (start == 0) {
                    Matcher m;

                    while ((read = input.read()) != LexerInput.EOF && (m = VARIABLE_RE.matcher(input.readText())).find()) {
                        if (m.end() < input.readLength())
                            break;
                    }

                    if (read != LexerInput.EOF) {
                        input.backup(1);
                    }

                    return fact.createToken(DeclarativeHintTokenId.VARIABLE);
                }

                if (whitespaceLength == start) {
                    input.backup(input.readLength() - whitespaceLength);
                    return fact.createToken(DeclarativeHintTokenId.WHITESPACE);
                }

                input.backup(input.readLength() - start);

                return fact.createToken(DeclarativeHintTokenId.JAVA_SNIPPET);
            }

            if (input.readLength() > 1) {
                String inputString = input.readText().toString();
                
                for (Entry<String, DeclarativeHintTokenId> e : BLOCK_TOKEN_START.entrySet()) {
                    if (!inputString.substring(0, inputString.length() - 1).endsWith(e.getKey()))
                        continue;

                    input.backup(1);
                    
                    Token<DeclarativeHintTokenId> preread = resolvePrereadText(e.getKey().length(), whitespaceLength);

                    if (preread != null) {
                        return preread;
                    }

                    return readBlockToken(e.getValue(), BLOCK_TOKEN_END.get(e.getValue()));
                }
                
                Token<DeclarativeHintTokenId> t = testToken(inputString, whitespaceLength, false);

                if (t == null && inputString.endsWith("::")) {
                    //need to disambiguate :: as a member ref separator; and as a snippet-conditions separator
                    int len = input.readLength();
                    if (len > 2) {
                        boolean colonColon = false;
                        StringBuilder ident = new StringBuilder();
                        boolean identFinished = false;
                        OUTER: while (true) {
                            int read2 = input.read();
                            if (Character.isWhitespace(read2)) {
                                if (ident.length() > 0) {
                                    identFinished = true;
                                }
                                continue;
                            }
                            if (identFinished || !Character.isJavaIdentifierPart((char) read2)) {
                                identFinished = true;
                                switch (read2) {
                                    case '(': case '&': case 'i': case '!':
                                        //condition
                                        colonColon = true;
                                        break OUTER;
                                    case ';':
                                        if (input.read() == ';') {
                                            input.backup(2);
                                            if ("otherwise".contentEquals(ident)) {
                                                //condition
                                                colonColon = true;
                                                break OUTER;
                                            }
                                        }
                                    default:
                                        //member ref
                                        break OUTER;
                                }
                            } else {
                                ident.append((char) read2);
                            }
                        }
                        if (colonColon) {
                            t = resolvePrereadText(input.readLength() - len + 2, whitespaceLength);
                        }
                    } else {
                        t = fact.createToken(DeclarativeHintTokenId.DOUBLE_COLON);
                    }
                }
                if (t != null) {
                    return t;
                }

            }

            read = input.read();
        }

        Token<DeclarativeHintTokenId> t = testToken(input.readText().toString(), whitespaceLength, true);

        if (t != null) {
            return t;
        }

        return fact.createToken(DeclarativeHintTokenId.JAVA_SNIPPET);
    }

    public Object state() {
        return null;
    }

    public void release() {}

    private Token<DeclarativeHintTokenId> testToken(String toTest, int whitespaceLength, boolean eof) {
        if (toTest.length() < 2 && !eof) return null;

        DeclarativeHintTokenId id = null;
        boolean exact = false;
        int backup = (-1);
        int add = eof ? 0 : 1;
        String snip = toTest.substring(0, toTest.length() - add);
        String lastImage = "";
        
        for (Entry<String, DeclarativeHintTokenId> e : TOKENS.entrySet()) {
            int i = snip.indexOf(e.getKey());
            if (i != (-1) && (snip.length() - i + 1 > backup || e.getKey().startsWith(lastImage)) && (e.getValue() != DeclarativeHintTokenId.COLON || !snip.substring(i).startsWith("::"))) {
                id = e.getValue();
                backup = snip.length() - i + 1;
                exact = i == 0;
                lastImage = e.getKey();
            }

            if (!eof) {
                for (int c = 1; c <= e.getKey().length(); c++) {
                    if (toTest.endsWith(e.getKey().substring(e.getKey().length() - c))) {
                        return null;
                    }
                }
            }
        }

        if (id == null) {
            return null;
        }

        if (exact) {
            if (input.readLength() - lastImage.length() + (eof ? 1 : 0) > 0)
                input.backup(input.readLength() - lastImage.length() + (eof ? 1 : 0));
            return fact.createToken(id);
        }
        
        Token<DeclarativeHintTokenId> t = resolvePrereadText(backup, whitespaceLength);

        if (t != null) {
            return t;
        } else {
            if (!eof)
                input.backup(1);
            
            return fact.createToken(id);
        }
    }

    private Token<DeclarativeHintTokenId> resolvePrereadText(int backupLength, int whitespaceLength) {
        if (whitespaceLength > 0) {
            if (input.readLengthEOF() == whitespaceLength + backupLength) {
                input.backup(input.readLengthEOF() - whitespaceLength);

                return fact.createToken(DeclarativeHintTokenId.WHITESPACE);
            } else {
                input.backup(backupLength);

                return fact.createToken(DeclarativeHintTokenId.JAVA_SNIPPET);
            }
        } else {
            if (input.readLengthEOF() == backupLength) {
                return null;
            } else {
                input.backup(backupLength);

                return fact.createToken(DeclarativeHintTokenId.JAVA_SNIPPET);
            }
        }
    }

    private Token<DeclarativeHintTokenId> readBlockToken(DeclarativeHintTokenId tokenId, String tokenEnd) {
        while (input.read() != LexerInput.EOF && !input.readText().toString().endsWith(tokenEnd))
            ;

        return fact.createToken(tokenId);
    }

    private static final Pattern DISPLAY_NAME_RE = Pattern.compile("'[^']*':");
    private static final Pattern VARIABLE_RE = Pattern.compile("\\$[A-Za-z0-9_$]+");

    private static final Map<String, DeclarativeHintTokenId> TOKENS;
    private static final Map<String, DeclarativeHintTokenId> BLOCK_TOKEN_START;
    private static final Map<DeclarativeHintTokenId, String> BLOCK_TOKEN_END;

    static {
        Map<String, DeclarativeHintTokenId> map = new HashMap<String, DeclarativeHintTokenId>();

        map.put("=>", DeclarativeHintTokenId.LEADS_TO);
        map.put("&&", DeclarativeHintTokenId.AND);
        map.put("!", DeclarativeHintTokenId.NOT);
        map.put(";;", DeclarativeHintTokenId.DOUBLE_SEMICOLON);
        map.put("%%", DeclarativeHintTokenId.DOUBLE_PERCENT);
        map.put("instanceof", DeclarativeHintTokenId.INSTANCEOF);
        map.put("otherwise", DeclarativeHintTokenId.OTHERWISE);
        map.put(":", DeclarativeHintTokenId.COLON);

        TOKENS = Collections.unmodifiableMap(map);

        Map<String, DeclarativeHintTokenId> blockStartMap = new HashMap<String, DeclarativeHintTokenId>();

        blockStartMap.put("/*", DeclarativeHintTokenId.BLOCK_COMMENT);
        blockStartMap.put("//", DeclarativeHintTokenId.LINE_COMMENT);
        blockStartMap.put("<?", DeclarativeHintTokenId.JAVA_BLOCK);
        blockStartMap.put("<!", DeclarativeHintTokenId.OPTIONS);
        blockStartMap.put("'", DeclarativeHintTokenId.CHAR_LITERAL);
        blockStartMap.put("\"", DeclarativeHintTokenId.STRING_LITERAL);

        BLOCK_TOKEN_START = Collections.unmodifiableMap(blockStartMap);

        Map<DeclarativeHintTokenId, String> blockEndMap = new HashMap<DeclarativeHintTokenId, String>();

        blockEndMap.put(DeclarativeHintTokenId.BLOCK_COMMENT, "*/");
        blockEndMap.put(DeclarativeHintTokenId.LINE_COMMENT, "\n");
        blockEndMap.put(DeclarativeHintTokenId.JAVA_BLOCK, "?>");
        blockEndMap.put(DeclarativeHintTokenId.OPTIONS, ">");
        blockEndMap.put(DeclarativeHintTokenId.CHAR_LITERAL, "'");
        blockEndMap.put(DeclarativeHintTokenId.STRING_LITERAL, "\"");

        BLOCK_TOKEN_END = Collections.unmodifiableMap(blockEndMap);
    }
}
