package org.checkerframework.common.initializedfields;

import com.sun.source.tree.VariableTree;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Options;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import org.checkerframework.checker.signature.qual.BinaryName;
import org.checkerframework.common.accumulation.AccumulationAnnotatedTypeFactory;
import org.checkerframework.common.basetype.BaseTypeChecker;
import org.checkerframework.common.basetype.BaseTypeVisitor;
import org.checkerframework.common.initializedfields.qual.EnsuresInitializedFields;
import org.checkerframework.common.initializedfields.qual.InitializedFields;
import org.checkerframework.common.initializedfields.qual.InitializedFieldsBottom;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.GenericAnnotatedTypeFactory;
import org.checkerframework.framework.util.Contract;
import org.checkerframework.framework.util.ContractsFromMethod;
import org.checkerframework.javacutil.AnnotationBuilder;
import org.checkerframework.javacutil.BugInCF;
import org.checkerframework.javacutil.ElementUtils;
import org.checkerframework.javacutil.UserError;

/** The annotated type factory for the Initialized Fields Checker. */
public class InitializedFieldsAnnotatedTypeFactory extends AccumulationAnnotatedTypeFactory {

  /**
   * The type factories that determine whether the default value is consistent with the annotated
   * type. If empty, warn about all uninitialized fields.
   */
  List<GenericAnnotatedTypeFactory<?, ?, ?, ?>> defaultValueAtypeFactories;

  /**
   * Creates a new InitializedFieldsAnnotatedTypeFactory.
   *
   * @param checker the checker
   */
  public InitializedFieldsAnnotatedTypeFactory(BaseTypeChecker checker) {
    super(checker, InitializedFields.class, InitializedFieldsBottom.class);

    String[] checkerNames = getCheckerNames();

    defaultValueAtypeFactories = new ArrayList<>();
    for (String checkerName : checkerNames) {
      if (checkerName.equals(InitializedFieldsChecker.class.getCanonicalName())) {
        continue;
      }
      @SuppressWarnings("signature:argument") // -processor is a binary name
      GenericAnnotatedTypeFactory<?, ?, ?, ?> atf = getTypeFactory(checkerName);
      if (atf != null) {
        defaultValueAtypeFactories.add(atf);
      }
    }

    this.postInit();
  }

  /**
   * Returns the names of the annotation processors that are being run.
   *
   * @return the names of the annotation processors that are being run
   */
  @SuppressWarnings("JdkObsolete") // ClassLoader.getResources returns an Enumeration
  private String[] getCheckerNames() {
    Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
    String processorArg = Options.instance(context).get("-processor");
    if (processorArg != null) {
      return processorArg.split(",");
    }
    try {
      String filename = "META-INF/services/javax.annotation.processing.Processor";
      List<String> lines = new ArrayList<>();
      Enumeration<URL> urls = getClass().getClassLoader().getResources(filename);
      while (urls.hasMoreElements()) {
        URL url = urls.nextElement();
        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
        lines.addAll(in.lines().collect(Collectors.toList()));
      }
      String[] result = lines.toArray(new String[0]);
      return result;
    } catch (IOException e) {
      throw new BugInCF(e);
    }
  }

  /**
   * Returns the type factory for the given annotation processor, if it is type-checker.
   *
   * @param processorName the fully-qualified class name of an annotation processor
   * @return the type factory for the given annotation processor, or null if it's not a checker
   */
  GenericAnnotatedTypeFactory<?, ?, ?, ?> getTypeFactory(@BinaryName String processorName) {
    try {
      Class<?> checkerClass = Class.forName(processorName);
      if (!BaseTypeChecker.class.isAssignableFrom(checkerClass)) {
        return null;
      }
      @SuppressWarnings("unchecked")
      BaseTypeChecker c =
          ((Class<? extends BaseTypeChecker>) checkerClass).getDeclaredConstructor().newInstance();
      c.init(processingEnv);
      c.initChecker();
      BaseTypeVisitor<?> v = c.createSourceVisitorPublic();
      GenericAnnotatedTypeFactory<?, ?, ?, ?> atf = v.createTypeFactoryPublic();
      if (atf == null) {
        throw new UserError("Cannot find %s; check the classpath or processorpath", processorName);
      }
      return atf;
    } catch (ClassNotFoundException
        | InstantiationException
        | InvocationTargetException
        | IllegalAccessException
        | NoSuchMethodException e) {
      throw new UserError("Problem instantiating " + processorName, e);
    }
  }

  @Override
  public InitializedFieldsContractsFromMethod getContractsFromMethod() {
    return new InitializedFieldsContractsFromMethod(this);
  }

  /**
   * A subclass of ContractsFromMethod that adds a postcondition contract to each constructor,
   * requiring that it initializes all fields.
   */
  private class InitializedFieldsContractsFromMethod extends ContractsFromMethod {
    /**
     * Creates an InitializedFieldsContractsFromMethod for the given factory.
     *
     * @param factory the type factory associated with the newly-created ContractsFromMethod
     */
    public InitializedFieldsContractsFromMethod(GenericAnnotatedTypeFactory<?, ?, ?, ?> factory) {
      super(factory);
    }

    @Override
    public Set<Contract.Postcondition> getPostconditions(ExecutableElement executableElement) {
      Set<Contract.Postcondition> result = super.getPostconditions(executableElement);

      // Only process methods defined in source code being type-checked.
      if (declarationFromElement(executableElement) != null) {

        if (executableElement.getKind() == ElementKind.CONSTRUCTOR) {
          // It's a constructor

          String[] fieldsToInitialize =
              fieldsToInitialize((TypeElement) executableElement.getEnclosingElement());
          if (fieldsToInitialize.length != 0) {

            AnnotationMirror initializedFieldsAnno;
            {
              AnnotationBuilder builder =
                  new AnnotationBuilder(processingEnv, InitializedFields.class);
              builder.setValue("value", fieldsToInitialize);
              initializedFieldsAnno = builder.build();
            }
            AnnotationMirror ensuresAnno;
            {
              AnnotationBuilder builder =
                  new AnnotationBuilder(processingEnv, EnsuresInitializedFields.class);
              builder.setValue("value", new String[] {"this"});
              builder.setValue("fields", fieldsToInitialize);
              ensuresAnno = builder.build();
            }
            Contract.Postcondition ensuresContract =
                new Contract.Postcondition("this", initializedFieldsAnno, ensuresAnno);

            result.add(ensuresContract);
          }
        }
      }

      return result;
    }
  }

  /**
   * Returns the fields that the constructor must initialize. These are the fields F declared in
   * this class that satisfy all of the following conditions:
   *
   * <ul>
   *   <li>F is a non-final field (if final, Java will issue a warning, so we don't need to).
   *   <li>F's declaration has no initializer.
   *   <li>No initialization block or static initialization block sets the field. (This is handled
   *       automatically because dataflow visits (static) initialization blocks as part of the
   *       constructor.)
   *   <li>F's annotated type is not consistent with the default value (0, 0.0, false, or null)
   * </ul>
   *
   * @param type the type whose fields to list
   * @return the fields whose type is not consistent with the default value, so the constructor must
   *     initialize them
   */
  // It is a bit wasteful that this is recomputed for each constructor.
  private String[] fieldsToInitialize(TypeElement type) {
    List<String> result = new ArrayList<String>();

    for (Element member : type.getEnclosedElements()) {

      if (member.getKind() != ElementKind.FIELD) {
        continue;
      }

      VariableElement field = (VariableElement) member;
      if (ElementUtils.isFinal(field)) {
        continue;
      }

      VariableTree fieldTree = (VariableTree) declarationFromElement(field);
      if (fieldTree.getInitializer() != null) {
        continue;
      }

      if (!defaultValueIsOK(field)) {
        result.add(field.getSimpleName().toString());
      }
    }

    return result.toArray(new String[result.size()]);
  }

  /**
   * Returns true if the default field value (0, false, or null) is consistent with the field's
   * declared type.
   *
   * @param field a field
   * @return true if the default field value is consistent with the field's declared type
   */
  private boolean defaultValueIsOK(VariableElement field) {
    if (defaultValueAtypeFactories.isEmpty()) {
      return false;
    }

    for (GenericAnnotatedTypeFactory<?, ?, ?, ?> defaultValueAtypeFactory :
        defaultValueAtypeFactories) {
      defaultValueAtypeFactory.setRoot(root);

      AnnotatedTypeMirror fieldType = defaultValueAtypeFactory.getAnnotatedType(field);
      AnnotatedTypeMirror defaultValueType =
          defaultValueAtypeFactory.getDefaultValueAnnotatedType(fieldType.getUnderlyingType());
      if (!defaultValueAtypeFactory.getTypeHierarchy().isSubtype(defaultValueType, fieldType)) {
        return false;
      }
    }

    return true;
  }
}
