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

import com.google.idea.blaze.base.lang.buildfile.language.BuildFileLanguage;
import com.google.idea.blaze.base.lang.buildfile.language.BuildFileType;
import com.google.idea.blaze.base.lang.buildfile.lexer.BuildToken;
import com.google.idea.blaze.base.lang.buildfile.lexer.TokenKind;
import com.google.idea.blaze.base.lang.buildfile.psi.Argument;
import com.google.idea.blaze.base.lang.buildfile.psi.Expression;
import com.google.idea.blaze.base.lang.buildfile.psi.FuncallExpression;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.impl.PsiFileFactoryImpl;
import com.intellij.testFramework.LightVirtualFile;

/** Creates dummy BuildElements, e.g. for renaming purposes. */
public class BuildElementGenerator {

  public static BuildElementGenerator getInstance(Project project) {
    return ServiceManager.getService(project, BuildElementGenerator.class);
  }

  private static final String DUMMY_FILENAME = "dummy.bzl";

  private final Project project;

  public BuildElementGenerator(Project project) {
    this.project = project;
  }

  public PsiFile createDummyFile(String contents) {
    PsiFileFactory factory = PsiFileFactory.getInstance(project);
    LightVirtualFile virtualFile =
        new LightVirtualFile(DUMMY_FILENAME, BuildFileType.INSTANCE, contents);
    PsiFile psiFile =
        ((PsiFileFactoryImpl) factory)
            .trySetupPsiForFile(virtualFile, BuildFileLanguage.INSTANCE, false, true);
    assert psiFile != null;
    return psiFile;
  }

  public ASTNode createNameIdentifier(String name) {
    PsiFile dummyFile = createDummyFile(name);
    ASTNode referenceNode = dummyFile.getNode().getFirstChildNode();
    ASTNode nameNode = referenceNode.getFirstChildNode();
    if (nameNode.getElementType() != BuildToken.IDENTIFIER) {
      throw new RuntimeException(
          "Expecting an IDENTIFIER node directly below the BuildFile PSI element");
    }
    return nameNode;
  }

  public ASTNode createStringNode(String contents) {
    PsiFile dummyFile = createDummyFile('"' + contents + '"');
    ASTNode literalNode = dummyFile.getNode().getFirstChildNode();
    ASTNode stringNode = literalNode.getFirstChildNode();
    assert (stringNode.getElementType() == BuildToken.fromKind(TokenKind.STRING));
    return stringNode;
  }

  public Argument.Keyword createKeywordArgument(String keyword, String value) {
    String dummyText = String.format("foo(%s = \"%s\")", keyword, value);
    FuncallExpression funcall = (FuncallExpression) createExpressionFromText(dummyText);
    return (Argument.Keyword) funcall.getArguments()[0];
  }

  public Expression createExpressionFromText(String text) {
    PsiFile dummyFile = createDummyFile(text);
    PsiElement element = dummyFile.getFirstChild();
    if (element instanceof Expression) {
      return (Expression) element;
    }
    throw new RuntimeException("Could not parse text as expression: '" + text + "'");
  }
}
