// Copyright 2020 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.devtools.build.lib.skyframe.serialization.autocodec;

import static com.google.devtools.build.lib.skyframe.serialization.autocodec.TypeOperations.getGeneratedName;
import static com.google.devtools.build.lib.skyframe.serialization.autocodec.TypeOperations.sanitizeTypeParameter;
import static com.google.devtools.build.lib.skyframe.serialization.autocodec.TypeOperations.writeGeneratedClassToFile;

import com.google.auto.service.AutoService;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.skyframe.serialization.CodecScanningConstants;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.TypeSpec;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.tools.Diagnostic;

/** Javac annotation processor for static final fields that should be serialization constants. */
@AutoService(Processor.class)
public class SerializationConstantProcessor extends AbstractProcessor {
  private ProcessingEnvironment env;

  @Override
  public synchronized void init(ProcessingEnvironment processingEnv) {
    super.init(processingEnv);
    this.env = processingEnv;
  }

  @Override
  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    try {
      processInternal(roundEnv);
    } catch (SerializationProcessingException e) {
      // Reporting a message with ERROR kind will fail compilation.
      env.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), e.getElement());
    }
    return false;
  }

  private void processInternal(RoundEnvironment roundEnv) throws SerializationProcessingException {
    for (Element element : roundEnv.getElementsAnnotatedWith(SerializationConstant.class)) {
      JavaFile unused =
          writeGeneratedClassToFile(
              element, buildRegisteredSingletonClass((VariableElement) element, env), env);
    }
  }

  private static final ImmutableList<Modifier> REQUIRED_SINGLETON_MODIFIERS =
      ImmutableList.of(Modifier.STATIC, Modifier.FINAL);

  static TypeSpec buildRegisteredSingletonClass(VariableElement symbol, ProcessingEnvironment env)
      throws SerializationProcessingException {
    if (!symbol.getModifiers().containsAll(REQUIRED_SINGLETON_MODIFIERS)) {
      throw new SerializationProcessingException(
          symbol,
          "Field must be static and final to be annotated with @SerializationConstant or"
              + " @AutoCodec");
    }
    return TypeSpec.classBuilder(
            getGeneratedName(symbol, CodecScanningConstants.REGISTERED_SINGLETON_SUFFIX))
        .addModifiers(Modifier.PUBLIC)
        .addSuperinterface(RegisteredSingletonDoNotUse.class)
        .addField(
            FieldSpec.builder(
                    Object.class,
                    CodecScanningConstants.REGISTERED_SINGLETON_INSTANCE_VAR_NAME,
                    Modifier.PUBLIC,
                    Modifier.STATIC,
                    Modifier.FINAL)
                .initializer(
                    "$T.$L",
                    sanitizeTypeParameter(symbol.getEnclosingElement().asType(), env),
                    symbol.getSimpleName())
                .build())
        .build();
  }

  @Override
  public Set<String> getSupportedAnnotationTypes() {
    return ImmutableSet.of(SerializationConstant.class.getCanonicalName());
  }

  @Override
  public SourceVersion getSupportedSourceVersion() {
    return SourceVersion.latestSupported(); // Supports all versions of Java.
  }
}
