import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.TypeSpec;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;

public final class TypeNames {
  public static TypeSpec.Builder maybeAddGeneratedAnnotation(TypeSpec.Builder builder,
      Elements elements, SourceVersion sourceVersion, CodeBlock generatorName, Date date,
      CodeBlock comments) {
    if (elements == null) {
      throw new NullPointerException("elements == null");
    }
    if (sourceVersion == null) {
      throw new NullPointerException("sourceVersion == null");
    }
    if (generatorName == null) {
      throw new NullPointerException("generatorName == null");
    }
    String generatedName = sourceVersion.compareTo(SourceVersion.RELEASE_8) > 0
        ? "javax.annotation.processing.Generated" : "javax.annotation.Generated";
    TypeElement typeElement = elements.getTypeElement(generatedName);

    if (typeElement != null) {
      AnnotationSpec.Builder annotationBuilder = AnnotationSpec.builder(ClassName.get(typeElement))
          .addMember("value", generatorName);
      if (date != null) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        annotationBuilder.addMember("date", "$S", dateFormat.format(date));
      }
      if (comments != null) {
        annotationBuilder.addMember("comments", comments);
      }
      builder.addAnnotation(annotationBuilder.build());
    }
    return builder;
  }
}