/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * 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.idea.blaze.base.lang.buildfile.psi;

import com.google.idea.blaze.base.lang.buildfile.references.LabelReference;
import com.google.idea.blaze.base.lang.buildfile.references.LoadedSymbolReference;
import com.google.idea.blaze.base.lang.buildfile.references.PackageReferenceFragment;
import com.google.idea.blaze.base.lang.buildfile.references.QuoteType;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import javax.annotation.Nullable;

/** PSI node for string literal expressions */
public class StringLiteral extends BuildElementImpl implements LiteralExpression {

  /**
   * Removes the leading and trailing quotes. Naive implementation intended for resolving references
   * (in which case escaped characters, raw strings, etc. are unlikely).
   */
  public static String stripQuotes(String string) {
    // TODO: Handle escaped characters, etc. here?
    // (extract logic from BuildLexerBase.addStringLiteral)
    if (string.startsWith("\"\"\"")) {
      return string.length() <= 3 ? "" : string.substring(3, endTrimIndex(string, '"', 3));
    }
    if (string.startsWith("'''")) {
      return string.length() <= 3 ? "" : string.substring(3, endTrimIndex(string, '\'', 3));
    }
    if (string.startsWith("\"")) {
      return string.substring(1, endTrimIndex(string, '"', 1));
    }
    if (string.startsWith("'")) {
      return string.substring(1, endTrimIndex(string, '\'', 1));
    }
    return string;
  }

  private static int endTrimIndex(String string, char quoteChar, int numberQuoteChars) {
    int trimIndex = string.length();
    for (int i = 1;
        i <= Math.min(numberQuoteChars, string.length() - numberQuoteChars);
        i++, trimIndex--) {
      if (string.charAt(string.length() - i) != quoteChar) {
        break;
      }
    }
    return trimIndex;
  }

  public static QuoteType getQuoteType(@Nullable String rawText) {
    if (rawText == null) {
      return QuoteType.NoQuotes;
    }
    if (rawText.startsWith("\"\"\"")) {
      return QuoteType.TripleDouble;
    }
    if (rawText.startsWith("'''")) {
      return QuoteType.TripleSingle;
    }
    if (rawText.startsWith("'")) {
      return QuoteType.Single;
    }
    if (rawText.startsWith("\"")) {
      return QuoteType.Double;
    }
    return QuoteType.NoQuotes;
  }

  public StringLiteral(ASTNode astNode) {
    super(astNode);
  }

  @Override
  protected void acceptVisitor(BuildElementVisitor visitor) {
    visitor.visitStringLiteral(this);
  }

  /** Removes the leading and trailing quotes */
  public String getStringContents() {
    return stripQuotes(getText());
  }

  public QuoteType getQuoteType() {
    return getQuoteType(getText());
  }

  /**
   * Labels are taken to reference: - the actual target they reference - the BUILD package specified
   * before the colon (only if explicitly present)
   */
  @Override
  public PsiReference[] getReferences() {
    PsiReference primaryReference = getReference();
    if (primaryReference instanceof LabelReference) {
      return new PsiReference[] {
        primaryReference, new PackageReferenceFragment((LabelReference) primaryReference)
      };
    }
    return primaryReference != null
        ? new PsiReference[] {primaryReference}
        : PsiReference.EMPTY_ARRAY;
  }

  /** The primary reference -- this is the target referenced by the full label */
  @Nullable
  @Override
  public PsiReference getReference() {
    PsiElement parent = getParent();
    if (parent instanceof LoadStatement) {
      LoadStatement load = (LoadStatement) parent;
      StringLiteral importNode = load.getImportPsiElement();
      if (importNode == null) {
        return null;
      }
      LabelReference importReference = new LabelReference(importNode, false);
      if (this.equals(importNode)) {
        return importReference;
      }
      return new LoadedSymbolReference(this, importReference);
    }
    return new LabelReference(this, true);
  }

  public boolean insideLoadStatement() {
    return getParentType() == BuildElementTypes.LOAD_STATEMENT;
  }

  @Override
  public String getPresentableText() {
    return getText();
  }
}
