/*
 * Copyright 2019 The Android Open Source Project
 *
 * 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 android.processor.view.inspector;


import android.processor.view.inspector.InspectableClassModel.IntEnumEntry;
import android.processor.view.inspector.InspectableClassModel.IntFlagEntry;
import android.processor.view.inspector.InspectableClassModel.Property;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.NameAllocator;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;

import javax.annotation.processing.Filer;
import javax.lang.model.element.Modifier;

/**
 * Generates a source file defining a {@link android.view.inspector.InspectionCompanion}.
 */
public final class InspectionCompanionGenerator {
    private final Filer mFiler;
    private final Class mRequestingClass;

    /**
     * The class name for {@code R.java}.
     */
    private static final ClassName R_CLASS_NAME = ClassName.get("android", "R");

    /**
     * The class name of {@link android.view.inspector.InspectionCompanion}.
     */
    private static final ClassName INSPECTION_COMPANION = ClassName.get(
            "android.view.inspector", "InspectionCompanion");

    /**
     * The class name of {@link android.view.inspector.PropertyMapper}.
     */
    private static final ClassName PROPERTY_MAPPER = ClassName.get(
            "android.view.inspector", "PropertyMapper");

    /**
     * The class name of {@link android.view.inspector.PropertyReader}.
     */
    private static final ClassName PROPERTY_READER = ClassName.get(
            "android.view.inspector", "PropertyReader");

    /**
     * The class name of {@link android.view.inspector.IntEnumMapping}.
     */
    private static final ClassName INT_ENUM_MAPPING = ClassName.get(
            "android.view.inspector", "IntEnumMapping");

    /**
     * The class name of {@link android.view.inspector.IntFlagMapping}.
     */
    private static final ClassName INT_FLAG_MAPPING = ClassName.get(
            "android.view.inspector", "IntFlagMapping");

    /**
     * The {@code mPropertiesMapped} field.
     */
    private static final FieldSpec M_PROPERTIES_MAPPED = FieldSpec
            .builder(TypeName.BOOLEAN, "mPropertiesMapped", Modifier.PRIVATE)
            .initializer("false")
            .addJavadoc(
                    "Set by {@link #mapProperties($T)} once properties have been mapped.\n",
                    PROPERTY_MAPPER)
            .build();

    /**
     * The suffix of the generated class name after the class's binary name.
     */
    private static final String GENERATED_CLASS_SUFFIX = "$InspectionCompanion";

    /**
     * The null resource ID, copied to avoid a host dependency on platform code.
     *
     * @see android.content.res.Resources#ID_NULL
     */
    private static final int ID_NULL = 0;

    /**
     * @param filer A filer to write the generated source to
     * @param requestingClass A class object representing the class that invoked the generator
     */
    public InspectionCompanionGenerator(Filer filer, Class requestingClass) {
        mFiler = filer;
        mRequestingClass = requestingClass;
    }

    /**
     * Generate and write an inspection companion.
     *
     * @param model The model to generated
     * @throws IOException From the Filer
     */
    public void generate(InspectableClassModel model) throws IOException {
        generateFile(model).writeTo(mFiler);
    }

    /**
     * Generate a {@link JavaFile} from a model.
     *
     * This is package-public for testing.
     *
     * @param model The model to generate from
     * @return A generated file of an {@link android.view.inspector.InspectionCompanion}
     */
    JavaFile generateFile(InspectableClassModel model) {
        return JavaFile
                .builder(model.getClassName().packageName(), generateTypeSpec(model))
                .indent("    ")
                .build();
    }

    /**
     * Generate a {@link TypeSpec} for the {@link android.view.inspector.InspectionCompanion}
     * for the supplied model.
     *
     * @param model The model to generate from
     * @return A TypeSpec of the inspection companion
     */
    private TypeSpec generateTypeSpec(InspectableClassModel model) {
        final List<PropertyIdField> propertyIdFields = generatePropertyIdFields(model);

        TypeSpec.Builder builder = TypeSpec
                .classBuilder(generateClassName(model))
                .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                .addSuperinterface(ParameterizedTypeName.get(
                        INSPECTION_COMPANION, model.getClassName()))
                .addJavadoc("Inspection companion for {@link $T}.\n\n", model.getClassName())
                .addJavadoc("Generated by {@link $T}\n", getClass())
                .addJavadoc("on behalf of {@link $T}.\n", mRequestingClass)
                .addField(M_PROPERTIES_MAPPED);

        for (PropertyIdField propertyIdField : propertyIdFields) {
            builder.addField(propertyIdField.mFieldSpec);
        }

        builder.addMethod(generateMapProperties(propertyIdFields))
                .addMethod(generateReadProperties(model, propertyIdFields));

        generateGetNodeName(model).ifPresent(builder::addMethod);

        return builder.build();
    }

    /**
     * Build a list of {@link PropertyIdField}'s for a model.
     *
     * To insure idempotency of the generated code, this method sorts the list of properties
     * alphabetically by name.
     *
     * A {@link NameAllocator} is used to ensure that the field names are valid Java identifiers,
     * and it prevents overlaps in names by suffixing them as needed.
     *
     * @param model The model to get properties from
     * @return A list of properties and fields
     */
    private List<PropertyIdField> generatePropertyIdFields(InspectableClassModel model) {
        final NameAllocator nameAllocator = new NameAllocator();
        final List<Property> sortedProperties = new ArrayList<>(model.getAllProperties());
        final List<PropertyIdField> propertyIdFields = new ArrayList<>(sortedProperties.size());

        sortedProperties.sort(Comparator.comparing(Property::getName));

        for (Property property : sortedProperties) {
            // Format a property to a member field name like "someProperty" -> "mSomePropertyId"
            final String memberName = String.format(
                    "m%s%sId",
                    property.getName().substring(0, 1).toUpperCase(),
                    property.getName().substring(1));
            final FieldSpec fieldSpec = FieldSpec
                    .builder(TypeName.INT, nameAllocator.newName(memberName), Modifier.PRIVATE)
                    .addJavadoc("Property ID of {@code $L}.\n", property.getName())
                    .build();

            propertyIdFields.add(new PropertyIdField(fieldSpec, property));
        }

        return propertyIdFields;
    }

    /**
     * Generate a method definition for
     * {@link android.view.inspector.InspectionCompanion#getNodeName()}, if needed.
     *
     * If {@link InspectableClassModel#getNodeName()} is empty, This method returns an empty
     * optional, otherwise, it generates a simple method that returns the string value of the
     * node name.
     *
     * @param model The model to generate from
     * @return The method definition or an empty Optional
     */
    private Optional<MethodSpec> generateGetNodeName(InspectableClassModel model) {
        return model.getNodeName().map(nodeName -> MethodSpec.methodBuilder("getNodeName")
                .addAnnotation(Override.class)
                .addModifiers(Modifier.PUBLIC)
                .returns(String.class)
                .addStatement("return $S", nodeName)
                .build());
    }

    /**
     * Generate a method definition for
     * {@link android.view.inspector.InspectionCompanion#mapProperties(
     * android.view.inspector.PropertyMapper)}.
     *
     * @param propertyIdFields A list of properties to map to ID fields
     * @return The method definition
     */
    private MethodSpec generateMapProperties(List<PropertyIdField> propertyIdFields) {
        final MethodSpec.Builder builder = MethodSpec.methodBuilder("mapProperties")
                .addAnnotation(Override.class)
                .addModifiers(Modifier.PUBLIC)
                .addParameter(PROPERTY_MAPPER, "propertyMapper");

        propertyIdFields.forEach(p -> builder.addStatement(generatePropertyMapperInvocation(p)));
        builder.addStatement("$N = true", M_PROPERTIES_MAPPED);

        return builder.build();
    }

    /**
     * Generate a method definition for
     * {@link android.view.inspector.InspectionCompanion#readProperties(
     * Object, android.view.inspector.PropertyReader)}.
     *
     * @param model The model to generate from
     * @param propertyIdFields A list of properties and ID fields to read from
     * @return The method definition
     */
    private MethodSpec generateReadProperties(
            InspectableClassModel model,
            List<PropertyIdField> propertyIdFields) {
        final MethodSpec.Builder builder =  MethodSpec.methodBuilder("readProperties")
                .addAnnotation(Override.class)
                .addModifiers(Modifier.PUBLIC)
                .addParameter(model.getClassName(), "node")
                .addParameter(PROPERTY_READER, "propertyReader")
                .addCode(generatePropertyMapInitializationCheck());

        for (PropertyIdField propertyIdField : propertyIdFields) {
            builder.addStatement(
                    "propertyReader.read$L($N, node.$L)",
                    methodSuffixForPropertyType(propertyIdField.mProperty.getType()),
                    propertyIdField.mFieldSpec,
                    propertyIdField.mProperty.getAccessor().invocation());
        }

        return builder.build();
    }

    /**
     * Generate a statement maps a property with a {@link android.view.inspector.PropertyMapper}.
     *
     * @param propertyIdField The property model and ID field to generate from
     * @return A statement that invokes property mapper method
     */
    private CodeBlock generatePropertyMapperInvocation(PropertyIdField propertyIdField) {
        final CodeBlock.Builder builder = CodeBlock.builder();
        final Property property = propertyIdField.mProperty;
        final FieldSpec fieldSpec = propertyIdField.mFieldSpec;

        builder.add(
                "$N = propertyMapper.map$L($S,$W",
                fieldSpec,
                methodSuffixForPropertyType(property.getType()),
                property.getName());

        if (property.isAttributeIdInferrableFromR()) {
            builder.add("$T.attr.$L", R_CLASS_NAME, property.getName());
        } else {
            if (property.getAttributeId() == ID_NULL) {
                builder.add("$L", ID_NULL);
            } else {
                builder.add("$L", hexLiteral(property.getAttributeId()));
            }
        }

        switch (property.getType()) {
            case INT_ENUM:
                builder.add(",$W");
                builder.add(generateIntEnumMappingBuilder(property.getIntEnumEntries()));
                break;
            case INT_FLAG:
                builder.add(",$W");
                builder.add(generateIntFlagMappingBuilder(property.getIntFlagEntries()));
                break;
        }

        return builder.add(")").build();
    }

    /**
     * Generate a check that throws
     * {@link android.view.inspector.InspectionCompanion.UninitializedPropertyMapException}
     * if the properties haven't been initialized.
     *
     * <pre>
     *     if (!mPropertiesMapped) {
     *         throw new InspectionCompanion.UninitializedPropertyMapException();
     *     }
     * </pre>
     *
     * @return A codeblock containing the property map initialization check
     */
    private CodeBlock generatePropertyMapInitializationCheck() {
        return CodeBlock.builder()
                .beginControlFlow("if (!$N)", M_PROPERTIES_MAPPED)
                .addStatement(
                        "throw new $T()",
                        INSPECTION_COMPANION.nestedClass("UninitializedPropertyMapException"))
                .endControlFlow()
                .build();
    }

    /**
     * Generate an invocation of {@link android.view.inspector.IntEnumMapping.Builder}.
     *
     * <pre>
     *      new IntEnumMapping.Builder()
     *          .addValue("ONE", 1)
     *          .build()
     * </pre>
     *
     * @return A codeblock containing the an int enum mapping builder
     */
    private CodeBlock generateIntEnumMappingBuilder(List<IntEnumEntry> intEnumEntries) {
        final ArrayList<IntEnumEntry> sortedEntries = new ArrayList<>(intEnumEntries);
        sortedEntries.sort(Comparator.comparing(IntEnumEntry::getValue));

        final CodeBlock.Builder builder = CodeBlock.builder()
                .add("new $T()$>", INT_ENUM_MAPPING.nestedClass("Builder"));

        for (IntEnumEntry entry : sortedEntries) {
            builder.add("\n.addValue($S, $L)", entry.getName(), entry.getValue());
        }

        return builder.add("\n.build()$<").build();
    }

    private CodeBlock generateIntFlagMappingBuilder(List<IntFlagEntry> intFlagEntries) {
        final ArrayList<IntFlagEntry> sortedEntries = new ArrayList<>(intFlagEntries);
        sortedEntries.sort(Comparator.comparing(IntFlagEntry::getName));

        final CodeBlock.Builder builder = CodeBlock.builder()
                .add("new $T()$>", INT_FLAG_MAPPING.nestedClass("Builder"));

        for (IntFlagEntry entry : sortedEntries) {
            if (entry.hasMask()) {
                builder.add(
                        "\n.addFlag($S, $L, $L)",
                        entry.getName(),
                        hexLiteral(entry.getTarget()),
                        hexLiteral(entry.getMask()));
            } else {
                builder.add(
                        "\n.addFlag($S, $L)",
                        entry.getName(),
                        hexLiteral(entry.getTarget()));
            }
        }

        return builder.add("\n.build()$<").build();
    }

    /**
     * Generate the final class name for the inspection companion from the model's class name.
     *
     * The generated class is added to the same package as the source class. If the class in the
     * model is a nested class, the nested class names are joined with {@code "$"}. The suffix
     * {@code "$$InspectionCompanion"} is always added the the generated name. E.g.: For modeled
     * class {@code com.example.Outer.Inner}, the generated class name will be
     * {@code com.example.Outer$Inner$$InspectionCompanion}.
     *
     * @param model The model to generate from
     * @return A class name for the generated inspection companion class
     */
    private static ClassName generateClassName(InspectableClassModel model) {
        final ClassName className = model.getClassName();

        return ClassName.get(
                className.packageName(),
                String.join("$", className.simpleNames()) + GENERATED_CLASS_SUFFIX);
    }

    /**
     * Get the suffix for a {@code map} or {@code read} method for a property type.
     *
     * @param type The requested property type
     * @return A method suffix
     */
    private static String methodSuffixForPropertyType(Property.Type type) {
        switch (type) {
            case BOOLEAN:
                return "Boolean";
            case BYTE:
                return "Byte";
            case CHAR:
                return "Char";
            case DOUBLE:
                return "Double";
            case FLOAT:
                return "Float";
            case INT:
                return "Int";
            case LONG:
                return "Long";
            case SHORT:
                return "Short";
            case OBJECT:
                return "Object";
            case COLOR:
                return "Color";
            case GRAVITY:
                return "Gravity";
            case INT_ENUM:
                return "IntEnum";
            case INT_FLAG:
                return "IntFlag";
            case RESOURCE_ID:
                return "ResourceId";
            default:
                throw new NoSuchElementException(String.format("No such property type, %s", type));
        }
    }

    private static String hexLiteral(int value) {
        return String.format("0x%08x", value);
    }

    /**
     * Value class that holds a {@link Property} and a {@link FieldSpec} for that property.
     */
    private static final class PropertyIdField {
        private final FieldSpec mFieldSpec;
        private final Property mProperty;

        private PropertyIdField(FieldSpec fieldSpec, Property property) {
            mFieldSpec = fieldSpec;
            mProperty = property;
        }
    }
}
