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

import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import org.netbeans.api.lexer.Token;
import org.netbeans.api.lexer.TokenId;
import org.netbeans.api.lexer.TokenSequence;
import org.netbeans.api.lexer.TokenUtilities;
import org.netbeans.editor.BaseDocument;
import org.netbeans.modules.csl.api.OffsetRange;
import org.netbeans.modules.php.editor.lexer.LexUtilities;
import org.netbeans.modules.php.editor.lexer.PHPTokenId;
import org.netbeans.spi.editor.bracesmatching.BraceContext;
import org.netbeans.spi.editor.bracesmatching.BracesMatcher;
import org.netbeans.spi.editor.bracesmatching.MatcherContext;

/**
 * Implementation of BracesMatcher interface for PHP. It is based on original code
 * from PHPBracketCompleter.findMatching
 *
 * @author Marek Slama
 */
public final class PHPBracesMatcher implements BracesMatcher, BracesMatcher.ContextLocator {

    private static final Logger LOGGER = Logger.getLogger(PHPBracesMatcher.class.getName());

    MatcherContext context;

    private boolean findBackward;
    private int originOffset;
    private int matchingOffset;
    private String matchingText;

    public PHPBracesMatcher(MatcherContext context) {
        this.context = context;
    }

    @Override
    public int [] findOrigin() throws InterruptedException, BadLocationException {
        ((AbstractDocument) context.getDocument()).readLock();
        try {
            BaseDocument doc = (BaseDocument) context.getDocument();
            int offset = context.getSearchOffset();

            TokenSequence<?extends PHPTokenId> ts = LexUtilities.getPHPTokenSequence(doc, offset);

            if (ts != null) {
                // #240157
                if (searchForward(ts, offset)){
                    offset--;
                    if (offset < 0) {
                        return null;
                    }
                }

                ts.move(offset);

                if (!ts.moveNext()) {
                    return null;
                }

                Token<?extends PHPTokenId> token = ts.token();

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

                TokenId id = token.id();

                originOffset = ts.offset();
                if (LexUtilities.textEquals(token.text(), '(')) {
                    return new int [] {ts.offset(), ts.offset() + token.length()};
                } else if (LexUtilities.textEquals(token.text(), ')')) {
                    return new int [] {ts.offset(), ts.offset() + token.length()};
                } else if (id == PHPTokenId.PHP_CURLY_OPEN) {
                    return new int [] {ts.offset(), ts.offset() + token.length()};
                } else if (id == PHPTokenId.PHP_CURLY_CLOSE) {
                    return new int [] {ts.offset(), ts.offset() + token.length()};
                } else if (LexUtilities.textEquals(token.text(), '[')) {
                    return new int [] {ts.offset(), ts.offset() + token.length()};
                } else if (LexUtilities.textEquals(token.text(), ']')) {
                    return new int [] {ts.offset(), ts.offset() + token.length()};
                } else if (LexUtilities.textEquals(token.text(), '$', '{')) {
                    return new int [] {ts.offset(), ts.offset() + token.length()};
                } else if (LexUtilities.textEquals(token.text(), ':')) {
                    do {
                        ts.movePrevious();
                        token = LexUtilities.findPreviousToken(ts,
                                Arrays.asList(PHPTokenId.PHP_IF, PHPTokenId.PHP_ELSE, PHPTokenId.PHP_ELSEIF,
                                PHPTokenId.PHP_FOR, PHPTokenId.PHP_FOREACH, PHPTokenId.PHP_WHILE, PHPTokenId.PHP_SWITCH,
                                PHPTokenId.PHP_OPENTAG, PHPTokenId.PHP_CURLY_CLOSE, PHPTokenId.PHP_CASE,
                                PHPTokenId.PHP_TOKEN));
                        id = token.id();
                    } while (id == PHPTokenId.PHP_TOKEN && !TokenUtilities.textEquals(token.text(), ":")); // NOI18N
                    if (id == PHPTokenId.PHP_IF || id == PHPTokenId.PHP_ELSE || id == PHPTokenId.PHP_ELSEIF
                            || id == PHPTokenId.PHP_FOR || id == PHPTokenId.PHP_FOREACH || id == PHPTokenId.PHP_WHILE
                            || id == PHPTokenId.PHP_SWITCH) {
                        ts.move(offset);
                        ts.moveNext();
                        token = ts.token();
                        return new int [] {ts.offset(), ts.offset() + token.length()};
                    }
                } else if (id == PHPTokenId.PHP_ENDFOR || id == PHPTokenId.PHP_ENDFOREACH
                        || id == PHPTokenId.PHP_ENDIF || id == PHPTokenId.PHP_ENDSWITCH
                        || id == PHPTokenId.PHP_ENDWHILE) {
                    return new int [] {ts.offset(), ts.offset() + token.length()};
                } else if (id == PHPTokenId.PHP_ELSEIF || id == PHPTokenId.PHP_ELSE) {
                    while (token.id() != PHPTokenId.PHP_CURLY_OPEN && !":".equals(token.text().toString()) && ts.moveNext()) {
                            token = LexUtilities.findNextToken(ts, Arrays.asList(PHPTokenId.PHP_TOKEN, PHPTokenId.PHP_CURLY_OPEN));
                    }
                    if (token.id() == PHPTokenId.PHP_TOKEN && TokenUtilities.textEquals(token.text(), ":") && ts.moveNext()) { // NOI18N
                        ts.move(offset);
                        ts.moveNext();
                        token = ts.token();
                        return new int [] {ts.offset(), ts.offset() + token.length()};
                    }
                } else {
                    originOffset = -1;
                }

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

    @Override
    public int [] findMatches() throws InterruptedException, BadLocationException {
        ((AbstractDocument) context.getDocument()).readLock();
        try {
            BaseDocument doc = (BaseDocument) context.getDocument();
            int offset = context.getSearchOffset();

            TokenSequence<?extends PHPTokenId> ts = LexUtilities.getPHPTokenSequence(doc, offset);

            if (ts != null) {
                // #240157
                if (searchForward(ts, offset)){
                    offset--;
                    if (offset < 0) {
                        return null;
                    }
                }

                ts.move(offset);

                if (!ts.moveNext()) {
                    return null;
                }

                Token<?extends PHPTokenId> token = ts.token();

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

                TokenId id = token.id();

                OffsetRange r = null;
                matchingText = ""; // NOI18N
                findBackward = false;
                try {
                    if (LexUtilities.textEquals(token.text(), '(')) {
                        matchingText = ")"; // NOI18N
                        r = LexUtilities.findFwd(doc, ts, PHPTokenId.PHP_TOKEN, '(', PHPTokenId.PHP_TOKEN, ')');
                        return new int [] {r.getStart(), r.getEnd() };
                    } else if (LexUtilities.textEquals(token.text(), ')')) {
                        findBackward = true;
                        matchingText = "("; // NOI18N
                        r = LexUtilities.findBwd(doc, ts, PHPTokenId.PHP_TOKEN, '(', PHPTokenId.PHP_TOKEN, ')');
                        return new int [] {r.getStart(), r.getEnd() };
                    } else if (id == PHPTokenId.PHP_CURLY_OPEN) {
                        matchingText = "}"; // NOI18N
                        r = LexUtilities.findFwd(doc, ts, PHPTokenId.PHP_CURLY_OPEN, '{', PHPTokenId.PHP_CURLY_CLOSE, '}');
                        return new int [] {r.getStart(), r.getEnd() };
                    } else if (id == PHPTokenId.PHP_CURLY_CLOSE) {
                        findBackward = true;
                        r = LexUtilities.findBwd(doc, ts, PHPTokenId.PHP_CURLY_OPEN, '{', PHPTokenId.PHP_CURLY_CLOSE, '}');
                        matchingText = r.getLength() == 1 ? "{" : "${"; // NOI18N
                        return new int [] {r.getStart(), r.getEnd() };
                    } else if (LexUtilities.textEquals(token.text(), '[')) {
                        matchingText = "]"; // NOI18N
                        r = LexUtilities.findFwd(doc, ts, PHPTokenId.PHP_TOKEN, '[', PHPTokenId.PHP_TOKEN, ']');
                        return new int [] {r.getStart(), r.getEnd() };
                    } else if (LexUtilities.textEquals(token.text(), ']')) {
                        matchingText = "["; // NOI18N
                        findBackward = true;
                        r = LexUtilities.findBwd(doc, ts, PHPTokenId.PHP_TOKEN, '[', PHPTokenId.PHP_TOKEN, ']');
                        return new int [] {r.getStart(), r.getEnd() };
                    } else if (LexUtilities.textEquals(token.text(), '$', '{')) {
                        matchingText = "}"; // NOI18N
                        r = LexUtilities.findFwd(doc, ts, PHPTokenId.PHP_TOKEN, '{', PHPTokenId.PHP_CURLY_CLOSE, '}');
                        return new int [] {r.getStart(), r.getEnd() };
                    } else if (LexUtilities.textEquals(token.text(), ':')) {
                        r = LexUtilities.findFwdAlternativeSyntax(doc, ts, token);
                        Token<? extends PHPTokenId> t = ts.token();
                        matchingText = t == null ? "" : t.text().toString(); // NOI18N
                        return new int [] {r.getStart(), r.getEnd() };
                    } else if (id == PHPTokenId.PHP_ENDFOR || id == PHPTokenId.PHP_ENDFOREACH
                            || id == PHPTokenId.PHP_ENDIF || id == PHPTokenId.PHP_ENDSWITCH
                            || id == PHPTokenId.PHP_ENDWHILE || id == PHPTokenId.PHP_ELSEIF
                            || id == PHPTokenId.PHP_ELSE) {
                        findBackward = true;
                        r = LexUtilities.findBwdAlternativeSyntax(doc, ts, token);
                        matchingText = ":"; // NOI18N
                        return new int [] {r.getStart(), r.getEnd() };
                    }
                } finally {
                    matchingOffset = r != null ? r.getStart() : -1;
                }
            }
            return null;
        } finally {
            ((AbstractDocument) context.getDocument()).readUnlock();
        }
    }

    private boolean searchForward(TokenSequence<? extends PHPTokenId> ts, int offset) {
        // if there is a brace token just before a caret position, search foward
        // e.g. if (isSomething()^), if (isSomething())^{
        // "^" is the caret
        if (context.isSearchingBackward()) {
            ts.move(offset);
            if (ts.movePrevious()) {
                Token<? extends PHPTokenId> previousToken = ts.token();
                if (previousToken != null && isBraceToken(previousToken)) {
                    return true;
                }
            }
        }
        return false;
    }

    private static boolean isBraceToken(Token<? extends PHPTokenId> token) {
        PHPTokenId id = token.id();
        return LexUtilities.textEquals(token.text(), '(') // NOI18N
                || LexUtilities.textEquals(token.text(), ')') // NOI18N
                || id == PHPTokenId.PHP_CURLY_OPEN
                || id == PHPTokenId.PHP_CURLY_CLOSE
                || LexUtilities.textEquals(token.text(), '[') // NOI18N
                || LexUtilities.textEquals(token.text(), ']') // NOI18N
                || LexUtilities.textEquals(token.text(), '$', '{') // NOI18N
                || LexUtilities.textEquals(token.text(), ':') // NOI18N
                || id == PHPTokenId.PHP_ENDFOR
                || id == PHPTokenId.PHP_ENDFOREACH
                || id == PHPTokenId.PHP_ENDIF
                || id == PHPTokenId.PHP_ENDSWITCH
                || id == PHPTokenId.PHP_ENDWHILE
                || id == PHPTokenId.PHP_ELSEIF
                || id == PHPTokenId.PHP_ELSE;
    }

    @Override
    public BraceContext findContext(int originOrMatchPosition) {
        if (findBackward && (matchingText.equals("{") || matchingText.equals(":"))) { // NOI18N
            if (originOffset != originOrMatchPosition) {
                return null;
            }
            try {
                return findContextBackwards();
            } catch (BadLocationException ex) {
                LOGGER.log(Level.WARNING, "incorrect offset: " + ex.offsetRequested(), ex);
            }
        }
        return null;
    }

    private BraceContext findContextBackwards() throws BadLocationException {
        ((AbstractDocument) context.getDocument()).readLock();
        try {
            BaseDocument doc = (BaseDocument) context.getDocument();
            TokenSequence<?extends PHPTokenId> ts = LexUtilities.getPHPTokenSequence(doc, matchingOffset);
            if (ts == null) {
                return null;
            }
            ts.move(matchingOffset);
            if (!ts.moveNext()) {
                return null;
            }
            List<PHPTokenId> lookfor = Arrays.asList(
                    PHPTokenId.PHP_CURLY_CLOSE, // terminator
                    PHPTokenId.PHP_CLASS, PHPTokenId.PHP_INTERFACE, PHPTokenId.PHP_TRAIT, PHPTokenId.PHP_FUNCTION,
                    PHPTokenId.PHP_FOR, PHPTokenId.PHP_FOREACH,
                    PHPTokenId.PHP_DO, PHPTokenId.PHP_WHILE,
                    PHPTokenId.PHP_TRY, PHPTokenId.PHP_CATCH, PHPTokenId.PHP_FINALLY,
                    PHPTokenId.PHP_IF, PHPTokenId.PHP_ELSE, PHPTokenId.PHP_ELSEIF,
                    PHPTokenId.PHP_SWITCH, PHPTokenId.PHP_USE
            );
            Token<? extends PHPTokenId> previousToken = LexUtilities.findPreviousToken(ts, lookfor);
            if (previousToken == null || previousToken.id() == PHPTokenId.PHP_CURLY_CLOSE) {
                return null;
            }

            PHPTokenId id = previousToken.id();
            switch (id) {
                case PHP_ELSE:
                    return getBraceContextForIfStatement(ts);
                default:
                    return getBraceContext(ts.offset());
            }
        } finally {
            ((AbstractDocument) context.getDocument()).readUnlock();
        }
    }

    private BraceContext getBraceContextForIfStatement(TokenSequence<? extends PHPTokenId> ts) throws BadLocationException {
        // find "if"
        int elseStart = ts.offset();
        if (elseStart < 0 || matchingOffset < elseStart) {
            return null;
        }
        int balance = 0;
        int ifStart = -1;
        int ifEnd = -1;
        String lastBrace = null;
        boolean found = false;
        boolean isAlternative = ":".equals(matchingText); // NOI18N
        while(ts.movePrevious()) {
            Token<? extends PHPTokenId> token = ts.token();
            PHPTokenId id = token.id();
            switch (id) {
                case PHP_ENDIF:
                    if (isAlternative) {
                        balance++;
                    }
                    break;
                case PHP_ELSEIF: // fall-through
                case PHP_IF:
                    if (matchingText.equals(lastBrace)) {
                        if (balance == 0) {
                            ifStart = ts.offset();
                            found = true;
                        }
                        if (isAlternative && id == PHPTokenId.PHP_IF) {
                            balance--;
                        }
                    }
                    break;
                case PHP_CURLY_CLOSE:
                    if (!isAlternative) {
                        balance++;
                    }
                    break;
                case PHP_CURLY_OPEN:
                    if (!isAlternative) {
                        balance--;
                        ifEnd = ts.offset();
                    }
                    lastBrace = token.text().toString();
                    break;
                case PHP_TOKEN:
                    if (isColon(token)) {
                        if (isAlternative) {
                            ifEnd = ts.offset();
                        }
                        lastBrace = token.text().toString();
                    }
                    if (isComplexSyntaxOpen(token)) {
                        if (!isAlternative) {
                            balance--;
                        }
                        lastBrace = token.text().toString();
                    }
                    break;
                default:
                    break;
            }
            if (found) {
                break;
            }
        }
        if (!found || ifStart == -1 || ifEnd == -1) {
            // broken code
            return getBraceContext(elseStart);
        }
        BraceContext braceContext = BraceContext.create(
                context.getDocument().createPosition(ifStart),
                context.getDocument().createPosition(ifEnd + 1) // + "{" or ":"
        );
        return braceContext.createRelated(
                context.getDocument().createPosition(elseStart),
                context.getDocument().createPosition(matchingOffset + 1) // + "{" or ":"
        );
    }

    private BraceContext getBraceContext(int start) throws BadLocationException {
        return BraceContext.create(
                context.getDocument().createPosition(start),
                context.getDocument().createPosition(matchingOffset + 1) // + "{" or ":"
        );
    }

    private static boolean isColon(Token<? extends PHPTokenId> token) {
        return token.id() == PHPTokenId.PHP_TOKEN && TokenUtilities.textEquals(token.text(), ":"); // NOI18N
    }

    private static boolean isComplexSyntaxOpen(Token<? extends PHPTokenId> token) {
        return token.id() == PHPTokenId.PHP_TOKEN && TokenUtilities.textEquals(token.text(), "${"); // NOI18N
    }

}
