/*
 * Copyright (C) 2010 Google Inc.
 *
 * 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.doclava;

import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class Comment {
  static final Pattern FIRST_SENTENCE =
      Pattern.compile("((.*?)\\.)[ \t\r\n\\<](.*)", Pattern.DOTALL);

  private static final Set<String> KNOWN_TAGS = new HashSet<String>(Arrays.asList(new String[] {
          "@author",
          "@since",
          "@version",
          "@deprecated",
          "@undeprecate",
          "@docRoot",
          "@sdkCurrent",
          "@inheritDoc",
          "@more",
          "@samplecode",
          "@sample",
          "@include",
          "@serial",
      }));

  public Comment(String text, ContainerInfo base, SourcePositionInfo sp) {
    mText = text;
    mBase = base;
    // sp now points to the end of the text, not the beginning!
    mPosition = SourcePositionInfo.findBeginning(sp, text);
  }

  private void parseCommentTags(String text) {
      int i = 0;
      int length = text.length();
      while (i < length  && isWhitespaceChar(text.charAt(i++))) {}

      if (i <=  0) {
          return;
      }

      text = text.substring(i-1);
      length = text.length();

      if ("".equals(text)) {
          return;
      }

      int start = 0;
      int end = findStartOfBlock(text, start);


      // possible scenarios
      //    main and block(s)
      //    main only (end == -1)
      //    block(s) only (end == 0)

      switch (end) {
          case -1: // main only
              parseMainDescription(text, start, length);
              return;
          case 0: // block(s) only
              break;
          default: // main and block

              // find end of main because end is really the beginning of @
              parseMainDescription(text, start, findEndOfMainOrBlock(text, start, end));
              break;
      }

      // parse blocks
      for (start = end; start < length; start = end) {
          end = findStartOfBlock(text, start+1);

          if (end == -1) {
              parseBlock(text, start, length);
              break;
          } else {
              parseBlock(text, start, findEndOfMainOrBlock(text, start, end));
          }
      }

      // for each block
      //    make block parts
      //        end is either next @ at beginning of line or end of text
  }

  private int findEndOfMainOrBlock(String text, int start, int end) {
      for (int i = end-1; i >= start; i--) {
          if (!isWhitespaceChar(text.charAt(i))) {
              end = i+1;
              break;
          }
      }
      return end;
  }

  private void parseMainDescription(String mainDescription, int start, int end) {
      if (mainDescription == null) {
          return;
      }

      SourcePositionInfo pos = SourcePositionInfo.add(mPosition, mText, 0);
      while (start < end) {
          int startOfInlineTag = findStartIndexOfInlineTag(mainDescription, start, end);

          // if there are no more tags
          if (startOfInlineTag == -1) {
              tag(null, mainDescription.substring(start, end), true, pos);
              return;
          }

          //int endOfInlineTag = mainDescription.indexOf('}', startOfInlineTag);
          int endOfInlineTag = findEndIndexOfInlineTag(mainDescription, startOfInlineTag, end);

          // if there was only beginning tag
          if (endOfInlineTag == -1) {
              // parse all of main as one tag
              tag(null, mainDescription.substring(start, end), true, pos);
              return;
          }

          endOfInlineTag++; // add one to make it a proper ending index

          // do first part without an inline tag - ie, just plaintext
          tag(null, mainDescription.substring(start, startOfInlineTag), true, pos);

          // parse the rest of this section, the inline tag
          parseInlineTag(mainDescription, startOfInlineTag, endOfInlineTag, pos);

          // keep going
          start = endOfInlineTag;
      }
  }

  private int findStartIndexOfInlineTag(String text, int fromIndex, int toIndex) {
      for (int i = fromIndex; i < (toIndex-3); i++) {
          if (text.charAt(i) == '{' && text.charAt(i+1) == '@' && !isWhitespaceChar(text.charAt(i+2))) {
              return i;
          }
      }

      return -1;
  }

  private int findEndIndexOfInlineTag(String text, int fromIndex, int toIndex) {
      for (int i = fromIndex; i < toIndex; i++) {
          if (text.charAt(i) == '}') {
              return i;
          }
      }

      return -1;
  }

  private void parseInlineTag(String text, int start, int end, SourcePositionInfo pos) {
      int index = start+1;
      //int len = text.length();
      char c = text.charAt(index);
      // find the end of the tag name "@something"
      // need to do something special if we have '}'
      while (index < end && !isWhitespaceChar(c)) {

          // if this tag has no value, just return with tag name only
          if (c == '}') {
              // TODO - should value be "" or null?
              tag(text.substring(start+1, end), null, true, pos);
              return;
          }
          c = text.charAt(index++);
      }

      // don't parse things that don't have at least one extra character after @
      // probably should be plus 3
      // TODO - remove this - think it's fixed by change in parseMainDescription
      if (index == start+3) {
          return;
      }

      int endOfFirstPart = index-1;

      // get to beginning of tag value
      while (index < end && isWhitespaceChar(text.charAt(index++))) {}
      int startOfSecondPart = index-1;

      // +1 to get rid of opening brace and -1 to get rid of closing brace
      // maybe i wanna make this more elegant
      String tagName = text.substring(start+1, endOfFirstPart);
      String tagText = text.substring(startOfSecondPart, end-1);
      tag(tagName, tagText, true, pos);
  }


  /**
   * Finds the index of the start of a new block comment or -1 if there are
   * no more starts.
   * @param text The String to search
   * @param start the index of the String to start searching
   * @return The index of the start of a new block comment or -1 if there are
   * no more starts.
   */
  private int findStartOfBlock(String text, int start) {
      // how to detect we're at a new @
      //       if the chars to the left of it are \r or \n, we're at one
      //       if the chars to the left of it are ' ' or \t, keep looking
      //       otherwise, we're in the middle of a block, keep looking
      int index = text.indexOf('@', start);

      // no @ in text or index at first position
      if (index == -1 ||
              (index == 0 && text.length() > 1 && !isWhitespaceChar(text.charAt(index+1)))) {
          return index;
      }

      index = getPossibleStartOfBlock(text, index);

      int i = index-1; // start at the character immediately to the left of @
      char c;
      while (i >= 0) {
          c = text.charAt(i--);

          // found a new block comment because we're at the beginning of a line
          if (c == '\r' || c == '\n') {
              return index;
          }

          // there is a non whitespace character to the left of the @
          // before finding a new line, keep searching
          if (c != ' ' && c != '\t') {
              index = getPossibleStartOfBlock(text, index+1);
              i = index-1;
          }

          // some whitespace character, so keep looking, we might be at a new block comment
      }

      return -1;
  }

  private int getPossibleStartOfBlock(String text, int index) {
      while (isWhitespaceChar(text.charAt(index+1)) || !isWhitespaceChar(text.charAt(index-1))) {
          index = text.indexOf('@', index+1);

          if (index == -1 || index == text.length()-1) {
              return -1;
          }
      }

      return index;
  }

  private void parseBlock(String text, int startOfBlock, int endOfBlock) {
      SourcePositionInfo pos = SourcePositionInfo.add(mPosition, mText, startOfBlock);
      int index = startOfBlock;

      for (char c = text.charAt(index);
              index < endOfBlock && !isWhitespaceChar(c); c = text.charAt(index++)) {}

      //
      if (index == startOfBlock+1) {
          return;
      }

      int endOfFirstPart = index-1;
      if (index == endOfBlock) {
          // TODO - should value be null or ""
          tag(text.substring(startOfBlock,
                  findEndOfMainOrBlock(text, startOfBlock, index)), "", false, pos);
          return;
      }


      // get to beginning of tag value
      while (index < endOfBlock && isWhitespaceChar(text.charAt(index++))) {}
      int startOfSecondPart = index-1;

      tag(text.substring(startOfBlock, endOfFirstPart),
              text.substring(startOfSecondPart, endOfBlock), false, pos);
  }

  private boolean isWhitespaceChar(char c) {
      switch (c) {
          case ' ':
          case '\r':
          case '\t':
          case '\n':
              return true;
      }
      return false;
  }

  private void tag(String name, String text, boolean isInline, SourcePositionInfo pos) {
    /*
     * String s = isInline ? "inline" : "outofline"; System.out.println("---> " + s + " name=[" +
     * name + "] text=[" + text + "]");
     */
    if (name == null) {
      mInlineTagsList.add(new TextTagInfo("Text", "Text", text, pos));
    } else if (name.equals("@param")) {
      mParamTagsList.add(new ParamTagInfo("@param", "@param", text, mBase, pos));
    } else if (name.equals("@see")) {
      mSeeTagsList.add(new SeeTagInfo("@see", "@see", text, mBase, pos));
    } else if (name.equals("@link")) {
      mInlineTagsList.add(new SeeTagInfo(name, "@see", text, mBase, pos));
    } else if (name.equals("@linkplain")) {
      mInlineTagsList.add(new SeeTagInfo(name, "@linkplain", text, mBase, pos));
    } else if (name.equals("@value")) {
      mInlineTagsList.add(new SeeTagInfo(name, "@value", text, mBase, pos));
    } else if (name.equals("@throws") || name.equals("@exception")) {
      mThrowsTagsList.add(new ThrowsTagInfo("@throws", "@throws", text, mBase, pos));
    } else if (name.equals("@return")) {
      mReturnTagsList.add(new ParsedTagInfo("@return", "@return", text, mBase, pos));
    } else if (name.equals("@deprecated")) {
      if (text.length() == 0) {
        Errors.error(Errors.MISSING_COMMENT, pos, "@deprecated tag with no explanatory comment");
        text = "No replacement.";
      }
      mDeprecatedTagsList.add(new ParsedTagInfo("@deprecated", "@deprecated", text, mBase, pos));
    } else if (name.equals("@literal")) {
      mInlineTagsList.add(new LiteralTagInfo(text, pos));
    } else if (name.equals("@code")) {
      mInlineTagsList.add(new CodeTagInfo(text, pos));
    } else if (name.equals("@hide") || name.equals("@removed")
            || name.equals("@pending") || name.equals("@doconly")) {
      // nothing
    } else if (name.equals("@attr")) {
      AttrTagInfo tag = new AttrTagInfo("@attr", "@attr", text, mBase, pos);
      mAttrTagsList.add(tag);
      Comment c = tag.description();
      if (c != null) {
        for (TagInfo t : c.tags()) {
          mInlineTagsList.add(t);
        }
      }
    } else if (name.equals("@undeprecate")) {
      mUndeprecateTagsList.add(new TextTagInfo("@undeprecate", "@undeprecate", text, pos));
    } else if (name.equals("@include") || name.equals("@sample")) {
      mInlineTagsList.add(new SampleTagInfo(name, "@include", text, mBase, pos));
    } else {
      boolean known = KNOWN_TAGS.contains(name);
      if (!known) {
        known = Doclava.knownTags.contains(name);
      }
      if (!known) {
        Errors.error(Errors.UNKNOWN_TAG, pos == null ? null : new SourcePositionInfo(pos),
            "Unknown tag: " + name);
      }
      TagInfo t = new TextTagInfo(name, name, text, pos);
      if (isInline) {
        mInlineTagsList.add(t);
      } else {
        mTagsList.add(t);
      }
    }
  }

  private void parseBriefTags() {
    int N = mInlineTagsList.size();

    // look for "@more" tag, which means that we might go past the first sentence.
    int more = -1;
    for (int i = 0; i < N; i++) {
      if (mInlineTagsList.get(i).name().equals("@more")) {
        more = i;
      }
    }
    if (more >= 0) {
      for (int i = 0; i < more; i++) {
        mBriefTagsList.add(mInlineTagsList.get(i));
      }
    } else {
      for (int i = 0; i < N; i++) {
        TagInfo t = mInlineTagsList.get(i);
        if (t.name().equals("Text")) {
          Matcher m = FIRST_SENTENCE.matcher(t.text());
          if (m.matches()) {
            String text = m.group(1);
            TagInfo firstSentenceTag = new TagInfo(t.name(), t.kind(), text, t.position());
            mBriefTagsList.add(firstSentenceTag);
            break;
          }
        }
        mBriefTagsList.add(t);

      }
    }
  }

  public TagInfo[] tags() {
    init();
    return mInlineTags;
  }

  public TagInfo[] tags(String name) {
    init();
    ArrayList<TagInfo> results = new ArrayList<TagInfo>();
    int N = mInlineTagsList.size();
    for (int i = 0; i < N; i++) {
      TagInfo t = mInlineTagsList.get(i);
      if (t.name().equals(name)) {
        results.add(t);
      }
    }
    return results.toArray(TagInfo.getArray(results.size()));
  }

  public ParamTagInfo[] paramTags() {
    init();
    return mParamTags;
  }

  public SeeTagInfo[] seeTags() {
    init();
    return mSeeTags;
  }

  public ThrowsTagInfo[] throwsTags() {
    init();
    return mThrowsTags;
  }

  public TagInfo[] returnTags() {
    init();
    return mReturnTags;
  }

  public TagInfo[] deprecatedTags() {
    init();
    return mDeprecatedTags;
  }

  public TagInfo[] undeprecateTags() {
    init();
    return mUndeprecateTags;
  }

  public AttrTagInfo[] attrTags() {
    init();
    return mAttrTags;
  }

  public TagInfo[] briefTags() {
    init();
    return mBriefTags;
  }

  public boolean isHidden() {
    if (mHidden == null) {
      mHidden = !Doclava.checkLevel(Doclava.SHOW_HIDDEN) &&
          (mText != null) && (mText.indexOf("@hide") >= 0 || mText.indexOf("@pending") >= 0);
    }
    return mHidden;
  }

  public boolean isRemoved() {
    if (mRemoved == null) {
        mRemoved = !Doclava.checkLevel(Doclava.SHOW_HIDDEN) &&
            (mText != null) && (mText.indexOf("@removed") >= 0);
    }

    return mRemoved;
  }

  public boolean isDocOnly() {
    if (mDocOnly == null) {
      mDocOnly = (mText != null) && (mText.indexOf("@doconly") >= 0);
    }
    return mDocOnly;
  }

  public boolean isDeprecated() {
    if (mDeprecated == null) {
      mDeprecated = (mText != null) && (mText.indexOf("@deprecated") >= 0);
    }

    return mDeprecated;
  }

  private void init() {
    if (!mInitialized) {
      initImpl();
    }
  }

  private void initImpl() {
    isHidden();
    isRemoved();
    isDocOnly();
    isDeprecated();

    // Don't bother parsing text if we aren't generating documentation.
    if (Doclava.parseComments()) {
        parseCommentTags(mText);
        parseBriefTags();
    } else {
      // Forces methods to be recognized by findOverriddenMethods in MethodInfo.
      mInlineTagsList.add(new TextTagInfo("Text", "Text", mText,
          SourcePositionInfo.add(mPosition, mText, 0)));
    }

    mText = null;
    mInitialized = true;

    mInlineTags = mInlineTagsList.toArray(TagInfo.getArray(mInlineTagsList.size()));
    mParamTags = mParamTagsList.toArray(ParamTagInfo.getArray(mParamTagsList.size()));
    mSeeTags = mSeeTagsList.toArray(SeeTagInfo.getArray(mSeeTagsList.size()));
    mThrowsTags = mThrowsTagsList.toArray(ThrowsTagInfo.getArray(mThrowsTagsList.size()));
    mReturnTags = ParsedTagInfo.joinTags(
        mReturnTagsList.toArray(ParsedTagInfo.getArray(mReturnTagsList.size())));
    mDeprecatedTags = ParsedTagInfo.joinTags(
        mDeprecatedTagsList.toArray(ParsedTagInfo.getArray(mDeprecatedTagsList.size())));
    mUndeprecateTags = mUndeprecateTagsList.toArray(TagInfo.getArray(mUndeprecateTagsList.size()));
    mAttrTags = mAttrTagsList.toArray(AttrTagInfo.getArray(mAttrTagsList.size()));
    mBriefTags = mBriefTagsList.toArray(TagInfo.getArray(mBriefTagsList.size()));

    mParamTagsList = null;
    mSeeTagsList = null;
    mThrowsTagsList = null;
    mReturnTagsList = null;
    mDeprecatedTagsList = null;
    mUndeprecateTagsList = null;
    mAttrTagsList = null;
    mBriefTagsList = null;
  }

  boolean mInitialized;
  Boolean mHidden = null;
  Boolean mRemoved = null;
  Boolean mDocOnly = null;
  Boolean mDeprecated = null;
  String mText;
  ContainerInfo mBase;
  SourcePositionInfo mPosition;
  int mLine = 1;

  TagInfo[] mInlineTags;
  TagInfo[] mTags;
  ParamTagInfo[] mParamTags;
  SeeTagInfo[] mSeeTags;
  ThrowsTagInfo[] mThrowsTags;
  TagInfo[] mBriefTags;
  TagInfo[] mReturnTags;
  TagInfo[] mDeprecatedTags;
  TagInfo[] mUndeprecateTags;
  AttrTagInfo[] mAttrTags;

  ArrayList<TagInfo> mInlineTagsList = new ArrayList<TagInfo>();
  ArrayList<TagInfo> mTagsList = new ArrayList<TagInfo>();
  ArrayList<ParamTagInfo> mParamTagsList = new ArrayList<ParamTagInfo>();
  ArrayList<SeeTagInfo> mSeeTagsList = new ArrayList<SeeTagInfo>();
  ArrayList<ThrowsTagInfo> mThrowsTagsList = new ArrayList<ThrowsTagInfo>();
  ArrayList<TagInfo> mBriefTagsList = new ArrayList<TagInfo>();
  ArrayList<ParsedTagInfo> mReturnTagsList = new ArrayList<ParsedTagInfo>();
  ArrayList<ParsedTagInfo> mDeprecatedTagsList = new ArrayList<ParsedTagInfo>();
  ArrayList<TagInfo> mUndeprecateTagsList = new ArrayList<TagInfo>();
  ArrayList<AttrTagInfo> mAttrTagsList = new ArrayList<AttrTagInfo>();


}
