/*
 * Copyright 2000-2013 JetBrains s.r.o.
 *
 * Licensed 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.jetbrains.plugins.groovy.lang.groovydoc.lexer;

import com.intellij.lexer.Lexer;
import com.intellij.lexer.LexerBase;
import com.intellij.lexer.LookAheadLexer;
import com.intellij.lexer.MergingLexerAdapter;
import com.intellij.psi.TokenType;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;

/**
 * @author ilyas
 */
public class GroovyDocLexer extends MergingLexerAdapter implements GroovyDocTokenTypes {

  private static final TokenSet TOKENS_TO_MERGE = TokenSet.create(
      mGDOC_COMMENT_DATA,
      TokenType.WHITE_SPACE
  );

  public GroovyDocLexer() {
    super(new LookAheadLexer(new AsteriskStripperLexer(new _GroovyDocLexer())) {
      @Override
      protected void lookAhead(Lexer baseLexer) {
        if (baseLexer.getTokenType() == mGDOC_INLINE_TAG_END) {
          advanceAs(baseLexer, mGDOC_COMMENT_DATA);
          return;
        }
        
        if (baseLexer.getTokenType() == mGDOC_INLINE_TAG_START) {
          int depth = 0;
          while (true) {
            IElementType type = baseLexer.getTokenType();
            if (type == null) {
              break;
            }
            if (type == mGDOC_INLINE_TAG_START) {
              depth++;
            }
            advanceLexer(baseLexer);
            if (type == mGDOC_INLINE_TAG_END) {
              depth--;
            }
            if (depth == 0) {
              break;
            }
          }
          return;
        }
        
        super.lookAhead(baseLexer);
      }
    }, TOKENS_TO_MERGE);
  }

  private static class AsteriskStripperLexer extends LexerBase {
    private final _GroovyDocLexer myFlexLexer;
    private CharSequence myBuffer;
    private int myBufferIndex;
    private int myBufferEndOffset;
    private int myTokenEndOffset;
    private int myState;
    private IElementType myTokenType;
    private boolean myAfterLineBreak;
    private boolean myInLeadingSpace;

    public AsteriskStripperLexer(final _GroovyDocLexer lexer) {
      myFlexLexer = lexer;
    }

    public final void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
      myBuffer = buffer;
      myBufferIndex = startOffset;
      myBufferEndOffset = endOffset;
      myTokenType = null;
      myTokenEndOffset = startOffset;
      myFlexLexer.reset(myBuffer, startOffset, endOffset, initialState);
    }

    public int getState() {
      return myState;
    }

    @NotNull
    public CharSequence getBufferSequence() {
      return myBuffer;
    }

    public int getBufferEnd() {
      return myBufferEndOffset;
    }

    public final IElementType getTokenType() {
      locateToken();
      return myTokenType;
    }

    public final int getTokenStart() {
      locateToken();
      return myBufferIndex;
    }

    public final int getTokenEnd() {
      locateToken();
      return myTokenEndOffset;
    }


    public final void advance() {
      locateToken();
      myTokenType = null;
    }

    protected final void locateToken() {
      if (myTokenType != null) return;
      _locateToken();

      if (myTokenType == TokenType.WHITE_SPACE) {
        myAfterLineBreak = CharArrayUtil.containLineBreaks(myBuffer, getTokenStart(), getTokenEnd());
      }
    }

    private void _locateToken() {
      if (myTokenEndOffset == myBufferEndOffset) {
        myTokenType = null;
        myBufferIndex = myBufferEndOffset;
        return;
      }

      myBufferIndex = myTokenEndOffset;

      if (myAfterLineBreak) {
        myAfterLineBreak = false;
        while (myTokenEndOffset < myBufferEndOffset && myBuffer.charAt(myTokenEndOffset) == '*' &&
            (myTokenEndOffset + 1 >= myBufferEndOffset || myBuffer.charAt(myTokenEndOffset + 1) != '/')) {
          myTokenEndOffset++;
        }

        myInLeadingSpace = true;
        if (myBufferIndex < myTokenEndOffset) {
          myTokenType = mGDOC_ASTERISKS;
          return;
        }
      }

      if (myInLeadingSpace) {
        myInLeadingSpace = false;
        boolean lf = false;
        while (myTokenEndOffset < myBufferEndOffset && Character.isWhitespace(myBuffer.charAt(myTokenEndOffset))) {
          if (myBuffer.charAt(myTokenEndOffset) == '\n') lf = true;
          myTokenEndOffset++;
        }

        final int state = myFlexLexer.yystate();
        if (state == _GroovyDocLexer.COMMENT_DATA ||
            myTokenEndOffset < myBufferEndOffset && (myBuffer.charAt(myTokenEndOffset) == '@' ||
                myBuffer.charAt(myTokenEndOffset) == '{' ||
                myBuffer.charAt(myTokenEndOffset) == '\"' ||
                myBuffer.charAt(myTokenEndOffset) == '<')) {
          myFlexLexer.yybegin(_GroovyDocLexer.COMMENT_DATA_START);
        }

        if (myBufferIndex < myTokenEndOffset) {
          myTokenType = lf || state == _GroovyDocLexer.PARAM_TAG_SPACE || state == _GroovyDocLexer.TAG_DOC_SPACE || state == _GroovyDocLexer.INLINE_TAG_NAME || state == _GroovyDocLexer.DOC_TAG_VALUE_IN_PAREN
              ? TokenType.WHITE_SPACE
              : mGDOC_COMMENT_DATA;

          return;
        }
      }

      flexLocateToken();
    }

    private void flexLocateToken() {
      try {
        myState = myFlexLexer.yystate();
        myFlexLexer.goTo(myBufferIndex);
        myTokenType = myFlexLexer.advance();
        myTokenEndOffset = myFlexLexer.getTokenEnd();
      }
      catch (IOException e) {
        // Can't be
      }
    }
  }
}
