/*
 * Copyright 2012-present Facebook, Inc.
 *
 * 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.facebook.buck.parcelable;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;

import java.io.File;
import java.io.IOException;
import java.util.Map;

import javax.annotation.Nullable;

public class Generator {

  private final ParcelableClass clazz;

  public Generator(ParcelableClass clazz) {
    this.clazz = Preconditions.checkNotNull(clazz);
  }

  public static String generateFromFile(File file) throws IOException {
    ParcelableClass parcelableClass = Parser.parse(file);
    return new Generator(parcelableClass).generate();
  }

  public String generate() throws IOException {
    PrintfStringBuilder out = new PrintfStringBuilder();

    out.appendLines(
        "/*",
        " * DO NOT MODIFY.",
        " * This file was auto-generated by Buck.",
        " */");

    out.appendLine("package %s;\n", clazz.getPackageName());

    for (String importLine : clazz.getImports()) {
      out.appendLine(importLine);
    }
    out.append('\n');

    String classDeclaration = clazz.getClassName();
    if (clazz.hasSuperClass()) {
      classDeclaration += " extends " + clazz.getSuperClassName();
    }
    out.appendLine("public class %s implements Parcelable {\n", classDeclaration);

    insertFields(out);

    // Jackson and other de-serializers often require a no-arg constructor.
    insertEmptyConstructor(out);

    insertFieldBasedConstructor(out);
    insertParcelBasedConstructor(out);
    insertDescribeContents(out);
    insertWriteToParcel(out);
    insertCreator(out);

    // Close top-level class definition.
    out.appendLine("}");

    return out.toString();
  }

  private void insertFields(PrintfStringBuilder out) throws IOException {
    final String defaultFieldVisibility = clazz.getDefaultFieldVisibility();
    for (ParcelableField field : clazz.getFields()) {
      if (field.getJsonProperty() != null) {
        String jsonProperty = field.getJsonProperty().isEmpty()
            ? ""
            : String.format("(\"%s\")", field.getJsonProperty());
        out.appendLine("  @JsonProperty%s", jsonProperty);
      }

      String visibility = field.getVisibility();
      if (visibility == null) {
        visibility = defaultFieldVisibility;
      }
      if (!visibility.isEmpty()) {
        visibility += ' ';
      }

      String mutability = field.isMutable() ? "" : "final ";
      out.appendLine("  %s%s%s %s;",
          visibility,
          mutability,
          field.getType(),
          field.getName());
      out.append('\n');
    }
  }

  private static final Map<String, String> TYPE_TO_DEFAULT_VALUE =
      ImmutableMap.<String, String>builder()
          .put("byte", "0")
          .put("int", "0")
          .put("long", "0")
          .put("float", "0")
          .put("double", "0")
          .put("boolean", "false")
          .build();

  private void insertEmptyConstructor(PrintfStringBuilder out) throws IOException {
    out.appendLine("  public %s() {", clazz.getClassName());
    if (clazz.hasSuperClass()) {
      out.appendLine("    super();");
    }

    for (ParcelableField field : clazz.getFields()) {
      String defaultValue = field.getDefaultValue();
      if (defaultValue == null) {
        defaultValue = TYPE_TO_DEFAULT_VALUE.get(field.getType());
        if (defaultValue == null) {
          defaultValue = "null";
        }
      }
      out.appendLine("    this.%s = %s;", field.getName(), defaultValue);
    }
    out.appendLine("  }");
    out.append('\n');
  }

  private void insertFieldBasedConstructor(PrintfStringBuilder out) throws IOException {
    out.appendLine("  public %s(", clazz.getClassName());

    if (clazz.hasSuperClass()) {
      String rawSuperParams = Strings.nullToEmpty(clazz.getRawSuperParams());
      if (!rawSuperParams.isEmpty() && !rawSuperParams.endsWith(",")) {
        rawSuperParams += ",";
      }
      out.appendLine("      %s", rawSuperParams);
    }

    final String defaultFieldVisibility = clazz.getDefaultFieldVisibility();
    Joiner.on(",\n").appendTo(out, Iterables.transform(clazz.getFields(),
        new Function<ParcelableField, String>() {

      @Override
      public String apply(ParcelableField field) {
        String visibility = field.getVisibility();
        if (visibility == null) {
          visibility = defaultFieldVisibility;
        }

        return String.format("      %s %s", field.getType(), field.getName());
      }

    }));

    // Close the param list and open the body.
    out.appendLine(") {");
    if (clazz.hasSuperClass()) {
      // rawSuperParams will be of the form "boolean isMale, int age".
      // They need to be filtered into param names to pass to super().
      String rawSuperParams = Strings.nullToEmpty(clazz.getRawSuperParams());
      String superParamNames = Joiner.on(", ").join(Iterables.transform(
          Splitter.on(',').trimResults().omitEmptyStrings().split(rawSuperParams),
          new Function<String, String>() {
            @Override
            public String apply(String typeAndName) {
              return typeAndName.split("\\s+")[1];
            }
          }));

      out.appendLine("    super(%s);", superParamNames);
    }

    for (ParcelableField field : clazz.getFields()) {
      out.appendLine("    this.%s = %s;", field.getName(), field.getName());
    }

    // Close constructor body.
    out.appendLine("  }");
  }

  private static final Map<String, ReadWriteMethod> SIMPLE_TYPE_MAPPINGS =
      ImmutableMap.<String, ReadWriteMethod>builder()
          .put("byte", ReadWriteMethod.both("Byte"))
          .put("double", ReadWriteMethod.both("Double"))
          .put("float", ReadWriteMethod.both("Float"))
          .put("int", ReadWriteMethod.both("Int"))
          .put("long", ReadWriteMethod.both("Long"))
          .put("String", ReadWriteMethod.both("String"))
          .put("List<String>", new ReadWriteMethod("createStringArrayList", "writeStringList"))
          .put("String[]", new ReadWriteMethod("createStringArray", "writeStringArray"))
          .build();

  private void insertParcelBasedConstructor(PrintfStringBuilder out) throws IOException {
    out.append('\n');
    out.appendLine("  public %s(Parcel parcel) {", clazz.getClassName());
    if (clazz.hasSuperClass()) {
      out.appendLine("    super(parcel);");
    }

    for (ParcelableField field : clazz.getFields()) {
      String type = field.getType();
      String fieldName = field.getName();
      ReadWriteMethod readWriteMethod = SIMPLE_TYPE_MAPPINGS.get(type);
      if (readWriteMethod != null && readWriteMethod.hasReadMethod()) {
        out.appendLine("    this.%s = parcel.%s();", fieldName, readWriteMethod.readMethod);
      } else if ("boolean".equals(type)) {
        out.appendLine("    this.%s = parcel.readByte() != 0;", fieldName);
      } else if ("List".equals(type)) {
        // If we do not have any type information, then we cannot use readTypedList().
        out.appendLine("    this.%s = parcel.readArrayList(null /* classLoader */);", fieldName);
      } else if (type.startsWith("List<")) {
        String genericType = type.substring("List<".length(), type.length() - 1);
        // We prefer readTypedList when we have type information, as it ostensibly stricter for
        // checking. May need to revisit this if the genericType is a supertype that has subclasses
        // with their own CREATOR that should be used.
        out.appendLine("    this.%s = Lists.newArrayList();", fieldName);
        out.appendLine("    parcel.readTypedList(this.%s, %s.CREATOR);", fieldName, genericType);
      } else {
        out.appendLine("    this.%s = parcel.readParcelable(%s.class.getClassLoader());",
            fieldName,
            field.getType());
      }
    }
    out.appendLine("  }");
  }

  private void insertDescribeContents(PrintfStringBuilder out) throws IOException {
    out.append('\n');
    out.appendLines(
        "  @Override",
        "  public int describeContents() {",
        "    return 0;",
        "  }");
  }

  private void insertWriteToParcel(PrintfStringBuilder out) throws IOException {
    out.append('\n');
    out.appendLines(
        "  @Override",
        "  public void writeToParcel(Parcel dest, int flags) {");
    for (ParcelableField field : clazz.getFields()) {
      String type = field.getType();
      String fieldName = field.getName();
      ReadWriteMethod readWriteMethod = SIMPLE_TYPE_MAPPINGS.get(type);
      if (readWriteMethod != null && readWriteMethod.hasWriteMethod()) {
        out.appendLine("    dest.%s(this.%s);", readWriteMethod.writeMethod, fieldName);
      } else if ("boolean".equals(type)) {
        out.appendLine("    dest.writeByte((byte)(this.%s ? 1 : 0));", fieldName);
      } else if ("List".equals(type)) {
        out.appendLine("    dest.writeList(this.%s);", fieldName);
      } else if (type.startsWith("List<")) {
        out.appendLine("    dest.writeTypedList(this.%s);", fieldName);
      } else {
        // Everything else is assumed to be a Parcelable.
        // This heuristic could be incorrect, so it will have to be improved over time.
        out.appendLine("    dest.writeParcelable(this.%s, flags);", fieldName);
      }
    }
    out.appendLines("  }");
  }

  private void insertCreator(PrintfStringBuilder out) throws IOException {
    out.append('\n');

    String creatorClassName = clazz.getCreatorClassName();
    out.appendLine("  public static final Parcelable.Creator<%s> CREATOR = " +
    		"new Parcelable.Creator<%s>() {",
    		creatorClassName,
    		creatorClassName);
    out.appendLine("    public %s createFromParcel(Parcel in) {", creatorClassName);
    out.appendLine("      return new %s(in);", creatorClassName);
    out.appendLine("    }");
    out.appendLine("    public %s[] newArray(int size) {", creatorClassName);
    out.appendLine("      return new %s[size];", creatorClassName);
    out.appendLine("    }");
    out.appendLine("  };");
  }

  private static class ReadWriteMethod {
    @Nullable private final String readMethod;
    @Nullable private final String writeMethod;

    private ReadWriteMethod(String readMethod, String writeMethod) {
      this.readMethod = readMethod;
      this.writeMethod = writeMethod;
    }

    public static ReadWriteMethod both(String name) {
      return new ReadWriteMethod("read" + name, "write" + name);
    }

    public boolean hasReadMethod() {
      return readMethod != null;
    }

    public boolean hasWriteMethod() {
      return writeMethod != null;
    }
  }
}
