/*
 * 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.javascript2.editor;

import java.util.List;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import org.netbeans.api.editor.mimelookup.MimeRegistration;
import org.netbeans.api.lexer.Language;
import org.netbeans.api.lexer.TokenHierarchy;
import org.netbeans.api.lexer.TokenSequence;
import org.netbeans.modules.javascript2.lexer.api.JsTokenId;
import org.netbeans.modules.javascript2.lexer.api.LexUtilities;
import org.netbeans.spi.editor.bracesmatching.BracesMatcher;
import org.netbeans.spi.editor.bracesmatching.BracesMatcherFactory;
import org.netbeans.spi.editor.bracesmatching.MatcherContext;
import org.netbeans.spi.editor.bracesmatching.support.BracesMatcherSupport;

/**
 *
 * @author Petr Hejl
 */
// major portion copied from java
public class JsBracesMatcher implements BracesMatcher {

    private static final char [] PAIRS = new char [] { '(', ')', '[', ']', '{', '}' }; //NOI18N

    private static final JsTokenId [] PAIR_TOKEN_IDS = new JsTokenId [] {
        JsTokenId.BRACKET_LEFT_PAREN, JsTokenId.BRACKET_RIGHT_PAREN,
        JsTokenId.BRACKET_LEFT_BRACKET, JsTokenId.BRACKET_RIGHT_BRACKET,
        JsTokenId.BRACKET_LEFT_CURLY, JsTokenId.BRACKET_RIGHT_CURLY
    };

    private final MatcherContext context;

    private final Language<JsTokenId> language;

    private int originOffset;
    private char originChar;
    private char matchingChar;
    private boolean backward;
    private List<TokenSequence<?>> sequences;
    private boolean templateExp;

    public JsBracesMatcher(MatcherContext context, Language<JsTokenId> language) {
        this.context = context;
        this.language = language;
    }

    @Override
    public int [] findOrigin() throws InterruptedException, BadLocationException {
        ((AbstractDocument) context.getDocument()).readLock();
        try {
            templateExp = false;
            int endOffset = -1;

            TokenSequence<? extends JsTokenId> testSeq = LexUtilities.getJsPositionedSequence(
                    context.getDocument(), context.getSearchOffset());
            if (testSeq != null) {
                if (testSeq.token().id() != JsTokenId.TEMPLATE_EXP_BEGIN && context.isSearchingBackward()) {
                    if (!testSeq.movePrevious() && context.getSearchOffset() - 1 >= context.getLimitOffset()) {
                        testSeq = LexUtilities.getJsPositionedSequence(
                                context.getDocument(), context.getSearchOffset() - 1);
                    }
                }
            }
            if (testSeq != null && testSeq.token().id() == JsTokenId.TEMPLATE_EXP_BEGIN) {
                originOffset = testSeq.offset();
                endOffset = originOffset + testSeq.token().length();
                originChar = '{'; // NOI18N
                matchingChar = '}'; // NOI18N
                backward = false;
            } else {
                int[] origin = BracesMatcherSupport.findChar(
                        context.getDocument(),
                        context.getSearchOffset(),
                        context.getLimitOffset(),
                        PAIRS
                );
                if (origin != null) {
                    originOffset = origin[0];
                    endOffset = originOffset + 1;
                    originChar = PAIRS[origin[1]];
                    matchingChar = PAIRS[origin[1] + origin[2]];
                    backward = origin[2] < 0;
                }
            }

            if (endOffset > 0) {
                TokenHierarchy<Document> th = TokenHierarchy.get(context.getDocument());
                // to get it work, there should not be checked previous ts. it can be different. see issue #250521
                sequences = getEmbeddedTokenSequences(th, originOffset, false, language);

                if (!sequences.isEmpty()) {
                    // Check special tokens
                    TokenSequence<?> seq = sequences.get(sequences.size() - 1);
                    seq.move(originOffset);
                    if (seq.moveNext()) {
                        if (seq.token().id() == JsTokenId.BLOCK_COMMENT
                                || seq.token().id() == JsTokenId.DOC_COMMENT
                                || seq.token().id() == JsTokenId.LINE_COMMENT
                                // remove once we have a lagueage
                                || seq.token().id() == JsTokenId.REGEXP
                                || seq.token().id() == JsTokenId.STRING) {
                            return null;
                        }
                        if (seq.token().id() == JsTokenId.TEMPLATE_EXP_BEGIN
                                || seq.token().id() == JsTokenId.TEMPLATE_EXP_END) {
                            templateExp = true;
                        }
                    }
                }

                return new int [] { originOffset, endOffset };
            } else {
                return null;
            }
        } finally {
            ((AbstractDocument) context.getDocument()).readUnlock();
        }
    }

    @Override
    public int [] findMatches() throws InterruptedException, BadLocationException {
        ((AbstractDocument) context.getDocument()).readLock();
        try {
            if (sequences != null && !sequences.isEmpty()) {
                TokenSequence<?> seq = sequences.get(sequences.size() - 1);

                TokenHierarchy<Document> th = TokenHierarchy.get(context.getDocument());
                List<TokenSequence<?>> list;
                if (backward) {
                    list = th.tokenSequenceList(seq.languagePath(), 0, originOffset);
                } else {
                    int offset = originOffset + 1;
                    if (templateExp) {
                        offset++;
                    }
                    list = th.tokenSequenceList(seq.languagePath(), offset, context.getDocument().getLength());
                }

                JsTokenId originId = getTokenId(originChar);
                JsTokenId lookingForId = getTokenId(matchingChar);
                if (templateExp) {
                    if (originChar == '}') { // NOI18N
                        originId = JsTokenId.TEMPLATE_EXP_END;
                        lookingForId = JsTokenId.TEMPLATE_EXP_BEGIN;
                    } else {
                        originId = JsTokenId.TEMPLATE_EXP_BEGIN;
                        lookingForId = JsTokenId.TEMPLATE_EXP_END;
                    }
                }
                int counter = 0;

                for(TokenSequenceIterator tsi = new TokenSequenceIterator(list, backward); tsi.hasMore(); ) {
                    TokenSequence<?> sq = tsi.getSequence();

                    if (originId == sq.token().id()) {
                        counter++;
                    } else if (lookingForId == sq.token().id()) {
                        if (counter == 0) {
                            return new int [] { sq.offset(), sq.offset() + sq.token().length() };
                        } else {
                            counter--;
                        }
                    }
                }
            }

            return null;
        } finally {
            ((AbstractDocument) context.getDocument()).readUnlock();
        }
    }

    public static List<TokenSequence<?>> getEmbeddedTokenSequences(
        TokenHierarchy<?> th, int offset, boolean backwardBias, Language<?> language) {
        List<TokenSequence<?>> sequences = th.embeddedTokenSequences(offset, backwardBias);

        for (int i = sequences.size() - 1; i >= 0; i--) {
            TokenSequence<?> seq = sequences.get(i);
            if (seq.language() == language) {
                break;
            } else {
                sequences.remove(i);
            }
        }

        return sequences;
    }

    private JsTokenId getTokenId(char ch) {
        for(int i = 0; i < PAIRS.length; i++) {
            if (PAIRS[i] == ch) {
                return PAIR_TOKEN_IDS[i];
            }
        }
        return null;
    }



    @MimeRegistration(mimeType = JsTokenId.JAVASCRIPT_MIME_TYPE, service = BracesMatcherFactory.class, position=0)
    public static class JsBracesMatcherFactory implements BracesMatcherFactory {

        @Override
        public BracesMatcher createMatcher(MatcherContext context) {
            return new JsBracesMatcher(context, JsTokenId.javascriptLanguage());
        }

    }

    @MimeRegistration(mimeType = JsTokenId.JSON_MIME_TYPE, service = BracesMatcherFactory.class, position=0)
    public static class JsonBracesMatcherFactory implements BracesMatcherFactory {

        @Override
        public BracesMatcher createMatcher(MatcherContext context) {
            return new JsBracesMatcher(context, JsTokenId.jsonLanguage());
        }

    }
}
