/*
 * Copyright 2021 Google LLC
 *
 * 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
 *
 *   https://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.android.enterprise.connectedapps.processor;

import static com.google.android.enterprise.connectedapps.processor.CommonClassNames.BACKGROUND_EXCEPTION_THROWER_CLASSNAME;
import static com.google.android.enterprise.connectedapps.processor.CommonClassNames.BINDER_CLASSNAME;
import static com.google.android.enterprise.connectedapps.processor.CommonClassNames.CONTEXT_CLASSNAME;
import static com.google.android.enterprise.connectedapps.processor.CommonClassNames.CROSS_PROFILE_CALLBACK_CLASSNAME;
import static com.google.android.enterprise.connectedapps.processor.CommonClassNames.CROSS_PROFILE_SENDER_CLASSNAME;
import static com.google.android.enterprise.connectedapps.processor.CommonClassNames.PARCEL_CALL_RECEIVER_CLASSNAME;
import static com.google.android.enterprise.connectedapps.processor.CommonClassNames.PARCEL_CLASSNAME;
import static com.google.android.enterprise.connectedapps.processor.CommonClassNames.PARCEL_UTILITIES_CLASSNAME;
import static com.google.android.enterprise.connectedapps.processor.ServiceGenerator.getConnectedAppsServiceClassName;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.stream.Collectors.joining;

import com.google.android.enterprise.connectedapps.annotations.CrossProfileConfiguration;
import com.google.android.enterprise.connectedapps.processor.containers.CrossProfileConfigurationInfo;
import com.google.android.enterprise.connectedapps.processor.containers.GeneratorContext;
import com.google.android.enterprise.connectedapps.processor.containers.ProviderClassInfo;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ArrayTypeName;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import java.util.List;
import javax.lang.model.element.Modifier;

/**
 * Generate the {@code *_Dispatcher} class for a single {@link CrossProfileConfiguration} annotated
 * class.
 *
 * <p>This class includes the dispatch of calls to providers.
 *
 * <p>This must only be used once. It should be used after {@link EarlyValidator} has been used to
 * validate that the annotated code is correct.
 */
final class DispatcherGenerator {

  private boolean generated = false;
  private final GeneratorContext generatorContext;
  private final GeneratorUtilities generatorUtilities;
  private final CrossProfileConfigurationInfo configuration;

  DispatcherGenerator(
      GeneratorContext generatorContext, CrossProfileConfigurationInfo configuration) {
    this.generatorContext = checkNotNull(generatorContext);
    this.generatorUtilities = new GeneratorUtilities(generatorContext);
    this.configuration = checkNotNull(configuration);
  }

  void generate() {
    if (generated) {
      throw new IllegalStateException("DispatcherGenerator#generate can only be called once");
    }
    generated = true;

    generateDispatcherClass();
  }

  private void generateDispatcherClass() {
    ClassName className = getDispatcherClassName(generatorContext, configuration);

    TypeSpec.Builder classBuilder =
        TypeSpec.classBuilder(className)
            .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
            .addJavadoc(
                "Class for dispatching calls to appropriate providers.\n\n"
                    + "<p>This uses a {@link $T} to construct calls before passing the completed"
                    + " call\n"
                    + "to a provider.\n",
                PARCEL_CALL_RECEIVER_CLASSNAME);

    classBuilder.addField(
        FieldSpec.builder(PARCEL_CALL_RECEIVER_CLASSNAME, "parcelCallReceiver")
            .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
            .initializer("new $T()", PARCEL_CALL_RECEIVER_CLASSNAME)
            .build());

    addCallMethod(classBuilder);
    addPrepareCallMethod(classBuilder);
    addFetchResponseMethod(classBuilder);

    generatorUtilities.writeClassToFile(className.packageName(), classBuilder);
  }

  private static void addPrepareCallMethod(TypeSpec.Builder classBuilder) {
    MethodSpec prepareCallMethod =
        MethodSpec.methodBuilder("prepareCall")
            .addModifiers(Modifier.PUBLIC)
            .addParameter(CONTEXT_CLASSNAME, "context")
            .addParameter(long.class, "callId")
            .addParameter(int.class, "blockId")
            .addParameter(int.class, "numBytes")
            .addParameter(ArrayTypeName.of(byte.class), "paramBytes")
            .addStatement("parcelCallReceiver.prepareCall(callId, blockId, numBytes, paramBytes)")
            .addJavadoc(
                "Store a block of bytes to be part of a future call to\n"
                    + "{@link #call(Context, long, int, long, int, byte[], ICrossProfileCallback)}."
                    + "\n\n"
                    + "@param callId Arbitrary identifier used to link together\n"
                    + "    {@link #prepareCall(Context, long, int, int, byte[])} and\n    "
                    + "{@link #call(Context, long, int, long, int, byte[], ICrossProfileCallback)}"
                    + " calls.\n"
                    + "@param blockId The (zero indexed) number of this block. Each block should"
                    + " be\n    {@link $1T#MAX_BYTES_PER_BLOCK} bytes so the total number of blocks"
                    + " is\n    {@code numBytes / $1T#MAX_BYTES_PER_BLOCK}.\n"
                    + "@param numBytes The total number of bytes being transferred (across all"
                    + " blocks for this call,\n    including the final {@link"
                    + " #call(Context, long, int, long, int, byte[], ICrossProfileCallback)}.\n"
                    + "@param paramBytes The bytes for this block. Should contain\n    {@link"
                    + " $1T#MAX_BYTES_PER_BLOCK} bytes.\n\n"
                    + "@see $2T#prepareCall(long, int, int, byte[])",
                CROSS_PROFILE_SENDER_CLASSNAME,
                PARCEL_CALL_RECEIVER_CLASSNAME)
            .build();
    classBuilder.addMethod(prepareCallMethod);
  }

  private static void addFetchResponseMethod(TypeSpec.Builder classBuilder) {
    MethodSpec prepareCallMethod =
        MethodSpec.methodBuilder("fetchResponse")
            .addModifiers(Modifier.PUBLIC)
            .addParameter(CONTEXT_CLASSNAME, "context")
            .addParameter(long.class, "callId")
            .addParameter(int.class, "blockId")
            .returns(ArrayTypeName.of(byte.class))
            .addStatement("return parcelCallReceiver.getPreparedResponse(callId, blockId)")
            .addJavadoc(
                "Fetch a response block if a previous call to\n {@link #call(Context, long, int,"
                    + " long, int, byte[], ICrossProfileCallback)} returned a\n byte array with"
                    + " 1 as the first byte.\n\n"
                    + "@param callId should be the same callId used with\n    {@link #call(Context,"
                    + " long, int, long, int, byte[], ICrossProfileCallback)}\n"
                    + "@param blockId The (zero indexed) number of the block to fetch.\n\n"
                    + "@see $1T#getPreparedResponse(long, int)\n",
                PARCEL_CALL_RECEIVER_CLASSNAME)
            .build();
    classBuilder.addMethod(prepareCallMethod);
  }

  private void addCallMethod(TypeSpec.Builder classBuilder) {
    CodeBlock.Builder methodCode = CodeBlock.builder();

    methodCode.beginControlFlow("try");

    methodCode.addStatement(
        "$1T parcel = parcelCallReceiver.getPreparedCall(callId, blockId, paramBytes)",
        PARCEL_CLASSNAME);

    List<ProviderClassInfo> providers = configuration.providers().asList();

    if (!providers.isEmpty()) {
      addProviderDispatch(methodCode, providers);
    }

    methodCode.addStatement(
        "throw new $T(\"Unknown type identifier \" + crossProfileTypeIdentifier)",
        IllegalArgumentException.class);

    methodCode.nextControlFlow("catch ($T e)", RuntimeException.class);
    // parcel is recycled in this method
    methodCode.addStatement("$1T throwableParcel = $1T.obtain()", PARCEL_CLASSNAME);
    methodCode.add("throwableParcel.writeInt(1); //errors\n");
    methodCode.addStatement(
        "$T.writeThrowableToParcel(throwableParcel, e)", PARCEL_UTILITIES_CLASSNAME);
    methodCode.addStatement(
        "$1T throwableBytes = parcelCallReceiver.prepareResponse(callId, throwableParcel)",
        ArrayTypeName.of(byte.class));
    methodCode.addStatement("throwableParcel.recycle()");

    methodCode.addStatement("$T.throwInBackground(e)", BACKGROUND_EXCEPTION_THROWER_CLASSNAME);

    methodCode.addStatement("return throwableBytes");
    methodCode.nextControlFlow("catch ($T e)", Error.class);

    // parcel is recycled in this method
    methodCode.addStatement("$1T throwableParcel = $1T.obtain()", PARCEL_CLASSNAME);
    methodCode.add("throwableParcel.writeInt(1); //errors\n");
    methodCode.addStatement(
            "$T.writeThrowableToParcel(throwableParcel, e)", PARCEL_UTILITIES_CLASSNAME);
    methodCode.addStatement(
            "$1T throwableBytes = parcelCallReceiver.prepareResponse(callId, throwableParcel)",
            ArrayTypeName.of(byte.class));
    methodCode.addStatement("throwableParcel.recycle()");

    methodCode.addStatement("$T.throwInBackground(e)", BACKGROUND_EXCEPTION_THROWER_CLASSNAME);

    methodCode.addStatement("return throwableBytes");
    methodCode.endControlFlow();

    MethodSpec callMethod =
        MethodSpec.methodBuilder("call")
            .addModifiers(Modifier.PUBLIC)
            .returns(ArrayTypeName.of(byte.class))
            .addAnnotation(AnnotationSpec.builder(SuppressWarnings.class)
                // Allow catching of RuntimeException
                .addMember("value", "\"CatchSpecificExceptionsChecker\"")
                .build())
            .addParameter(CONTEXT_CLASSNAME, "context")
            .addParameter(long.class, "callId")
            .addParameter(int.class, "blockId")
            .addParameter(long.class, "crossProfileTypeIdentifier")
            .addParameter(int.class, "methodIdentifier")
            .addParameter(ArrayTypeName.of(byte.class), "paramBytes")
            .addParameter(CROSS_PROFILE_CALLBACK_CLASSNAME, "callback")
            .addCode(methodCode.build())
            .addJavadoc(
                "Make a call, which will execute some annotated method and return a response.\n\n"
                    + "<p>The parameters to the call should be contained in a {@link $1T}"
                    + " marshalled into\n"
                    + "a byte array. If the byte array is larger than {@link"
                    + " $2T#MAX_BYTES_PER_BLOCK},\n"
                    + "then it should be separated into blocks of {@link"
                    + " $2T#MAX_BYTES_PER_BLOCK}\n"
                    + "bytes, and {@link #prepareCall(Context, long, int, int, byte[])} used to"
                    + " set all but the final\n"
                    + "block, before calling this method with the final block.\n\n"
                    + "<p>The response will be an array of bytes. If the response is complete (it"
                    + " fits into a single\n"
                    + "block), then the first byte will be 0, otherwise the first byte will be 1"
                    + " and the next 4 bytes\n"
                    + "will be an int representing the total size of the return value. The rest of"
                    + " the bytes are the\n"
                    + "first block of the return value. {@link #fetchResponse(Context, long, int)"
                    + " should be used to\n"
                    + "fetch further blocks.\n\n"
                    + "@param callId Arbitrary identifier used to link together\n"
                    + "    {@link #prepareCall(Context, long, int, int, byte[])} and\n"
                    + "    {@link #call(Context, long, int, long, int, byte[],"
                    + " ICrossProfileCallback)} calls.\n"
                    + "@param blockId The (zero indexed) number of this block. Each block should"
                    + " be\n    {@link CrossProfileSender#MAX_BYTES_PER_BLOCK} bytes so the total"
                    + " number of blocks is\n    {@code numBytes /"
                    + " CrossProfileSender#MAX_BYTES_PER_BLOCK}.\n"
                    + "@param crossProfileTypeIdentifier The generated identifier for the type"
                    + " which contains the\n    method being called.\n"
                    + "@param methodIdentifier The index of the method being called on the cross"
                    + " profile type.\n"
                    + "@param paramBytes The bytes for the final block, this will be merged with"
                    + " any blocks\n    previously set by a call to"
                    + " {@link #prepareCall(Context, long, int, int, byte[])}.\n"
                    + "@param callback A callback to be used if this is an asynchronous call."
                    + " Otherwise this should be\n    {@code null}.\n\n"
                    + "@see $3T#getPreparedCall(long, int, byte[])\n",
                PARCEL_CLASSNAME,
                CROSS_PROFILE_SENDER_CLASSNAME,
                PARCEL_CALL_RECEIVER_CLASSNAME)
            .build();

    classBuilder.addMethod(callMethod);
  }

  private void addProviderDispatch(
      CodeBlock.Builder methodCode, List<ProviderClassInfo> providers) {
    for (ProviderClassInfo provider : providers) {
      addProviderDispatchInner(methodCode, provider);
    }
  }

  private void addProviderDispatchInner(CodeBlock.Builder methodCode, ProviderClassInfo provider) {
    String condition =
        provider.allCrossProfileTypes().stream()
            .map(
                h ->
                    "crossProfileTypeIdentifier == "
                        + h.identifier()
                        + "L // "
                        + h.crossProfileTypeElement().getQualifiedName()
                        + "\n")
            .collect(joining(" || "));

    methodCode.beginControlFlow("if ($L)", condition);
    methodCode.addStatement(
        "$1T returnParcel = $2T.instance().call(context.getApplicationContext(),"
            + " crossProfileTypeIdentifier, methodIdentifier, parcel, callback)",
        PARCEL_CLASSNAME,
        InternalProviderClassGenerator.getInternalProviderClassName(generatorContext, provider));
    methodCode.addStatement(
        "$1T returnBytes = parcelCallReceiver.prepareResponse(callId, returnParcel)",
        ArrayTypeName.of(byte.class));
    methodCode.addStatement("parcel.recycle()");
    methodCode.addStatement("returnParcel.recycle()");
    methodCode.addStatement("return returnBytes");
    methodCode.endControlFlow();
  }

  static ClassName getDispatcherClassName(
      GeneratorContext generatorContext, CrossProfileConfigurationInfo configuration) {
    ClassName serviceName = getConnectedAppsServiceClassName(generatorContext, configuration);
    return ClassName.get(serviceName.packageName(), serviceName.simpleName() + "_Dispatcher");
  }
}
