// Copyright (C) 2016 The Android Open Source Project
//
// 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 com.google.gitiles.doc;

import com.google.common.collect.ImmutableSet;
import org.commonmark.Extension;
import org.commonmark.node.Block;
import org.commonmark.parser.Parser;
import org.commonmark.parser.Parser.ParserExtension;
import org.commonmark.parser.block.AbstractBlockParser;
import org.commonmark.parser.block.AbstractBlockParserFactory;
import org.commonmark.parser.block.BlockContinue;
import org.commonmark.parser.block.BlockStart;
import org.commonmark.parser.block.MatchedBlockParser;
import org.commonmark.parser.block.ParserState;

/**
 * CommonMark extension for block notes.
 *
 * <pre>
 * *** note
 * This is a note.
 * ***
 * </pre>
 */
public class BlockNoteExtension implements ParserExtension {
  private static final ImmutableSet<String> VALID_STYLES =
      ImmutableSet.of("note", "aside", "promo");

  public static Extension create() {
    return new BlockNoteExtension();
  }

  private BlockNoteExtension() {}

  @Override
  public void extend(Parser.Builder builder) {
    builder.customBlockParserFactory(new NoteParserFactory());
  }

  private static class NoteParser extends AbstractBlockParser {
    private final int indent;
    private final BlockNote block;
    private boolean done;

    NoteParser(int indent, String style) {
      this.indent = indent;
      block = new BlockNote();
      block.setClassName(style);
    }

    @Override
    public Block getBlock() {
      return block;
    }

    @Override
    public BlockContinue tryContinue(ParserState state) {
      if (done) {
        return BlockContinue.none();
      }
      if (state.getIndent() <= indent) {
        int s = state.getNextNonSpaceIndex();
        CharSequence line = state.getLine();
        if ("***".contentEquals(line.subSequence(s, line.length()))) {
          done = true;
          return BlockContinue.atIndex(line.length());
        }
      }
      return BlockContinue.atIndex(state.getIndex());
    }

    @Override
    public boolean isContainer() {
      return true;
    }

    @Override
    public boolean canContain(Block block) {
      return true;
    }
  }

  private static class NoteParserFactory extends AbstractBlockParserFactory {
    @Override
    public BlockStart tryStart(ParserState state, MatchedBlockParser matched) {
      int s = state.getNextNonSpaceIndex();
      CharSequence line = state.getLine();
      CharSequence text = line.subSequence(s, line.length());
      if (text.length() < 3 || !"***".contentEquals(text.subSequence(0, 3))) {
        return BlockStart.none();
      }

      String style = text.subSequence(3, text.length()).toString().trim();
      if (!VALID_STYLES.contains(style)) {
        return BlockStart.none();
      }

      return BlockStart.of(new NoteParser(state.getIndent(), style)).atIndex(line.length());
    }
  }
}
