/*
 * 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;

/**
 * Class that represents what you see in an link or see tag. This is factored out of SeeTagInfo so
 * it can be used elsewhere (like AttrTagInfo).
 */
public class LinkReference {

  private static final boolean DBG = false;

  /** The original text. */
  public String text;

  /** The kind of this tag, if we have a new suggestion after parsing. */
  public String kind;

  /** The user visible text. */
  public String label;

  /** The link. */
  public String href;

  /** Non-null for federated links */
  public String federatedSite;

  /** The {@link PackageInfo} if any. */
  public PackageInfo packageInfo;

  /** The {@link ClassInfo} if any. */
  public ClassInfo classInfo;

  /** The {@link MemberInfo} if any. */
  public MemberInfo memberInfo;

  /** The name of the referenced member PackageInfo} if any. */
  public String referencedMemberName;

  /** Set to true if everything is a-ok */
  public boolean good;

  /**
   * regex pattern to use when matching explicit 'a href' reference text
   */
  private static final Pattern HREF_PATTERN =
      Pattern.compile("^<a href=\"([^\"]*)\">([^<]*)</a>[ \n\r\t]*$", Pattern.CASE_INSENSITIVE);

  /**
   * regex pattern to use when matching double-quoted reference text
   */
  private static final Pattern QUOTE_PATTERN = Pattern.compile("^\"([^\"]*)\"[ \n\r\t]*$");

  /**
   * Parse and resolve a link string.
   * 
   * @param text the original text
   * @param base the class or whatever that this link is on
   * @param pos the original position in the source document
   * @return a new link reference. It always returns something. If there was an error, it logs it
   *         and fills in href and label with error text.
   */
  public static LinkReference parse(String text, ContainerInfo base, SourcePositionInfo pos,
      boolean printOnErrors) {
    LinkReference result = new LinkReference();
    result.text = text;

    int index;
    int len = text.length();
    int pairs = 0;
    int pound = -1;
    // split the string
    done: {
      for (index = 0; index < len; index++) {
        char c = text.charAt(index);
        switch (c) {
          case '(':
            pairs++;
            break;
          case '[':
            pairs++;
            break;
          case ')':
            pairs--;
            break;
          case ']':
            pairs--;
            break;
          case ' ':
          case '\t':
          case '\r':
          case '\n':
            if (pairs == 0) {
              break done;
            }
            break;
          case '#':
            if (pound < 0) {
              pound = index;
            }
            break;
        }
      }
    }
    if (index == len && pairs != 0) {
      Errors.error(Errors.UNRESOLVED_LINK, pos, "unable to parse link/see tag: " + text.trim());
      return result;
    }

    int linkend = index;

    for (; index < len; index++) {
      char c = text.charAt(index);
      if (!(c == ' ' || c == '\t' || c == '\r' || c == '\n')) {
        break;
      }
    }

    result.label = text.substring(index);

    String ref;
    String mem;
    if (pound == 0) {
      ref = null;
      mem = text.substring(1, linkend);
    } else if (pound > 0) {
      ref = text.substring(0, pound);
      mem = text.substring(pound + 1, linkend);
    } else {
      ref = text.substring(0, linkend);
      mem = null;
    }

    // parse parameters, if any
    String[] params = null;
    String[] paramDimensions = null;
    boolean varargs = false;
    if (mem != null) {
      index = mem.indexOf('(');
      if (index > 0) {
        ArrayList<String> paramList = new ArrayList<String>();
        ArrayList<String> paramDimensionList = new ArrayList<String>();
        len = mem.length();
        int start = index + 1;
        final int START = 0;
        final int TYPE = 1;
        final int NAME = 2;
        int dimension = 0;
        int arraypair = 0;
        int state = START;
        int typestart = 0;
        int typeend = -1;
        for (int i = start; i < len; i++) {
          char c = mem.charAt(i);
          switch (state) {
            case START:
              if (c != ' ' && c != '\t' && c != '\r' && c != '\n') {
                state = TYPE;
                typestart = i;
              }
              break;
            case TYPE:
              if (c == '.') {
                if (mem.length() > i+2 && mem.charAt(i+1) == '.' && mem.charAt(i+2) == '.') {
                  if (typeend < 0) {
                    typeend = i;
                  }
                  varargs = true;
                }
              } else if (c == '[') {
                if (typeend < 0) {
                  typeend = i;
                }
                dimension++;
                arraypair++;
              } else if (c == ']') {
                arraypair--;
              } else if (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
                if (typeend < 0) {
                  typeend = i;
                }
              } else {
                if (typeend >= 0 || c == ')' || c == ',') {
                  if (typeend < 0) {
                    typeend = i;
                  }
                  String s = mem.substring(typestart, typeend);
                  paramList.add(s);
                  s = "";
                  for (int j = 0; j < dimension; j++) {
                    s += "[]";
                  }
                  paramDimensionList.add(s);
                  state = START;
                  typeend = -1;
                  dimension = 0;
                  if (c == ',' || c == ')') {
                    state = START;
                  } else {
                    state = NAME;
                  }
                }
              }
              break;
            case NAME:
              if (c == ',' || c == ')') {
                state = START;
              }
              break;
          }

        }
        params = paramList.toArray(new String[paramList.size()]);
        paramDimensions = paramDimensionList.toArray(new String[paramList.size()]);
        mem = mem.substring(0, index);
      }
    }

    ClassInfo cl = null;
    if (base instanceof ClassInfo) {
      cl = (ClassInfo) base;
      if (DBG) System.out.println("-- chose base as classinfo");
    }

    if (ref == null) {
      if (DBG) System.out.println("-- ref == null");
      // no class or package was provided, assume it's this class
      if (cl != null) {
        if (DBG) System.out.println("-- assumed to be cl");
        result.classInfo = cl;
      }
    } else {
      if (DBG) System.out.println("-- they provided ref = " + ref);
      // they provided something, maybe it's a class or a package
      if (cl != null) {
        try {
          if (DBG) System.out.println("-- cl non-null");
          result.classInfo = cl.extendedFindClass(ref);
          if (result.classInfo == null) {
            if (DBG) System.out.println("-- cl.extendedFindClass was null");
            result.classInfo = cl.findClass(ref);
          }
          if (result.classInfo == null) {
            if (DBG) System.out.println("-- cl.findClass was null");
            result.classInfo = cl.findInnerClass(ref);
            if (DBG) if (result.classInfo == null) System.out.println("-- cl.findInnerClass was null");
          }
        } catch (RuntimeException e) {
          throw new RuntimeException("Failed to resolve class at " + pos, e);
        }
      }
      if (result.classInfo == null) {
        if (DBG) System.out.println("-- hitting up the Converter.obtainclass");
        result.classInfo = Converter.obtainClass(ref);
      }
      if (result.classInfo == null) {
        if (DBG) System.out.println("-- Converter.obtainClass was null");
        result.packageInfo = Converter.obtainPackage(ref);
      }
    }

    if (result.classInfo == null) {
        if (DBG) System.out.println("-- NO CLASS INFO");
    } else {
        Doclava.federationTagger.tag(result.classInfo);
        for (FederatedSite site : result.classInfo.getFederatedReferences()) {
          if (DBG) System.out.println("-- reg link = " + result.classInfo.htmlPage());
          if (DBG) System.out.println("-- fed link = " +
              site.linkFor(result.classInfo.htmlPage()));
        }
    }

    if (result.classInfo != null && mem != null) {
      // it's either a field or a method, prefer a field
      if (params == null) {
        FieldInfo field = result.classInfo.findField(mem);
        // findField looks in containing classes, so it might actually
        // be somewhere else; link to where it really is, not what they
        // typed.
        if (field != null) {
          result.classInfo = field.containingClass();
          result.memberInfo = field;
        }
      }
      if (result.memberInfo == null) {
        MethodInfo method = result.classInfo.findMethod(mem, params, paramDimensions, varargs);
        if (method != null) {
          result.classInfo = method.containingClass();
          result.memberInfo = method;
        }
      }
    }

    result.referencedMemberName = mem;
    if (params != null) {
      result.referencedMemberName = result.referencedMemberName + '(';
      len = params.length;
      if (len > 0) {
        len--;
        for (int i = 0; i < len; i++) {
          result.referencedMemberName =
              result.referencedMemberName + params[i] + paramDimensions[i] + ", ";
        }
        result.referencedMemberName =
            result.referencedMemberName + params[len] + paramDimensions[len];
      }
      result.referencedMemberName = result.referencedMemberName + ")";
    }

    // debugging spew
    if (false) {
      result.label = result.label + "/" + ref + "/" + mem + '/';
      if (params != null) {
        for (int i = 0; i < params.length; i++) {
          result.label += params[i] + "|";
        }
      }

      FieldInfo f = (result.memberInfo instanceof FieldInfo) ? (FieldInfo) result.memberInfo : null;
      MethodInfo m =
          (result.memberInfo instanceof MethodInfo) ? (MethodInfo) result.memberInfo : null;
      result.label =
          result.label + "/package="
              + (result.packageInfo != null ? result.packageInfo.name() : "") + "/class="
              + (result.classInfo != null ? result.classInfo.qualifiedName() : "") + "/field="
              + (f != null ? f.name() : "") + "/method=" + (m != null ? m.name() : "");

    }

    MethodInfo method = null;
    boolean skipHref = false;

    if (result.memberInfo != null && result.memberInfo.isExecutable()) {
      method = (MethodInfo) result.memberInfo;
    }

    if (DBG) System.out.println("----- label = " + result.label + ", text = '" + text + "'");
    if (text.startsWith("\"")) {
      // literal quoted reference (e.g., a book title)
      Matcher matcher = QUOTE_PATTERN.matcher(text);
      if (!matcher.matches()) {
        Errors.error(Errors.UNRESOLVED_LINK, pos, "unbalanced quoted link/see tag: " + text.trim());
        result.makeError();
        return result;
      }
      skipHref = true;
      result.label = matcher.group(1);
      result.kind = "@seeJustLabel";
      if (DBG) System.out.println(" ---- literal quoted reference");
    } else if (text.startsWith("<")) {
      // explicit "<a href" form
      Matcher matcher = HREF_PATTERN.matcher(text);
      if (!matcher.matches()) {
        Errors.error(Errors.UNRESOLVED_LINK, pos, "invalid <a> link/see tag: " + text.trim());
        result.makeError();
        return result;
      }
      result.href = matcher.group(1);
      result.label = matcher.group(2);
      result.kind = "@seeHref";
      if (DBG) System.out.println(" ---- explicit href reference");
    } else if (result.packageInfo != null) {
      result.href = result.packageInfo.htmlPage();
      if (result.label.length() == 0) {
        result.href = result.packageInfo.htmlPage();
        result.label = result.packageInfo.name();
      }
      if (DBG) System.out.println(" ---- packge reference");
    } else if (result.classInfo != null && result.referencedMemberName == null) {
      // class reference
      if (result.label.length() == 0) {
        result.label = result.classInfo.name();
      }
      setHref(result, result.classInfo, null);
      if (DBG) System.out.println(" ---- class reference");
    } else if (result.memberInfo != null) {
      // member reference
      ClassInfo containing = result.memberInfo.containingClass();
      if (result.memberInfo.isExecutable()) {
        if (result.referencedMemberName.indexOf('(') < 0) {
          result.referencedMemberName += method.flatSignature();
        }
      }
      if (result.label.length() == 0) {
        // Qualify labels that link beyond the base context
        final boolean beyondBase = base != null && containing != null
            && !base.qualifiedName().equals(containing.qualifiedName());
        if (beyondBase) {
          result.label = containing.name() + "." + result.referencedMemberName;
        } else {
          result.label = result.referencedMemberName;
        }
      }
      setHref(result, containing, result.memberInfo.anchor());
      if (DBG) System.out.println(" ---- member reference");
    }
    if (DBG) System.out.println("  --- href = '" + result.href + "'");

    if (result.href == null && !skipHref) {
      if (printOnErrors && (base == null || base.checkLevel())) {
        Errors.error(Errors.UNRESOLVED_LINK, pos, "Unresolved link/see tag \"" + text.trim()
            + "\" in " + ((base != null) ? base.qualifiedName() : "[null]"));
      }
      result.makeError();
    } else if (result.memberInfo != null && !result.memberInfo.checkLevel()) {
      if (printOnErrors && (base == null || base.checkLevel())) {
        Errors.error(Errors.HIDDEN_LINK, pos, "Link to hidden member: " + text.trim());
        result.href = null;
      }
      result.kind = "@seeJustLabel";
    } else if (result.classInfo != null && !result.classInfo.checkLevel()) {
      if (printOnErrors && (base == null || base.checkLevel())) {
        Errors.error(Errors.HIDDEN_LINK, pos, "Link to hidden class: " + text.trim() + " label="
            + result.label);
        result.href = null;
      }
      result.kind = "@seeJustLabel";
    } else if (result.packageInfo != null && !result.packageInfo.checkLevel()) {
      if (printOnErrors && (base == null || base.checkLevel())) {
        Errors.error(Errors.HIDDEN_LINK, pos, "Link to hidden package: " + text.trim());
        result.href = null;
      }
      result.kind = "@seeJustLabel";
    }

    result.good = true;

    return result;
  }

  public boolean checkLevel() {
    if (memberInfo != null) {
      return memberInfo.checkLevel();
    }
    if (classInfo != null) {
      return classInfo.checkLevel();
    }
    if (packageInfo != null) {
      return packageInfo.checkLevel();
    }
    return false;
  }

  /** turn this LinkReference into one with an error message */
  private void makeError() {
    // this.href = "ERROR(" + this.text.trim() + ")";
    this.href = null;
    if (this.label == null) {
      this.label = "";
    }
    this.label = "ERROR(" + this.label + "/" + text.trim() + ")";
  }

  static private void setHref(LinkReference reference, ClassInfo info, String member) {
    String htmlPage = info.htmlPage();
    if (member != null) {
      htmlPage = htmlPage + "#" + member;
    }

    Doclava.federationTagger.tag(info);
    if (!info.getFederatedReferences().isEmpty()) {
      FederatedSite site = info.getFederatedReferences().iterator().next();
      reference.href = site.linkFor(htmlPage);
      reference.federatedSite = site.name();
    } else {
      reference.href = htmlPage;
    }
  }

  /** private. **/
  private LinkReference() {}
}
