/*
 * Copyright 2013-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.java.abi;

import static javax.lang.model.element.ElementKind.CLASS;
import static javax.lang.model.element.ElementKind.ENUM;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.type.TypeMirror;

class TypeSummary implements Renderable {

  private String summary;

  public TypeSummary(RenderableTypes renderables, TypeElement element) {
    StringBuilder builder = new StringBuilder();

    appendTypeSignature(builder, element);

    Set<String> nestedTypes = new TreeSet<>();
    Set<String> contained = new TreeSet<>();
    // Ordering matters for enum constants.
    Set<String> enumValues = new LinkedHashSet<>();

    // Collect the enclosed elements, keeping enclosed types separately.
    for (Element enclosed : element.getEnclosedElements()) {
      StringBuilder elementBuilder = new StringBuilder();
      Renderable renderable = renderables.deriveFor(enclosed);
      renderable.appendTo(elementBuilder);

      if (renderable instanceof TypeSummary) {
        nestedTypes.add(elementBuilder.toString());
      } else if (renderable instanceof EnumConstantSummary) {
        enumValues.add(elementBuilder.toString());
      } else {
        contained.add(elementBuilder.toString());
      }
    }

    // Append enum constants
    for (String value : enumValues) {
      builder.append(value);
    }

    // Append all methods, fields, enum values and constants
    for (String text : contained) {
      builder.append(text);
    }

    // Append all nested types.
    if (!nestedTypes.isEmpty()) {
      builder.append("-----\n");
      Joiner.on("-----\n").appendTo(builder, nestedTypes);
    }
    summary = builder.toString();
  }

  private void appendTypeSignature(StringBuilder builder, TypeElement element) {
    ElementKind kind = element.getKind();

    builder.append(Annotations.printAnnotations(element.getAnnotationMirrors()));
    // Note that this causes all interfaces to be marked as "abstract". Since we're just generating
    // a text representation of the interface and not something perfect, I'm okay with this.
    builder.append(Modifiers.printModifiers(element.getModifiers()));

    switch (kind) {
      case ANNOTATION_TYPE:
        builder.append("@interface ");
        break;

      case CLASS:
        builder.append("class ");
        break;

      case ENUM:
        builder.append("enum ");
        break;

      case INTERFACE:
        builder.append("interface ");
        break;

      default:
        throw new RuntimeException("Unhandled kind: " + kind);
    }
    builder.append(element.getQualifiedName());

    List<? extends TypeParameterElement> typeParams = element.getTypeParameters();
    if (!typeParams.isEmpty()) {
      builder.append("<");
      Joiner.on(", ").appendTo(builder, typeParams);
      builder.append(">");
    }

    if (kind == CLASS) {
      builder.append(" extends ").append(element.getSuperclass());
    }

    // Sort the list alphabetically.
    List<String> converted = new ArrayList<>();
    for (TypeMirror mirror : element.getInterfaces()) {
      converted.add(mirror.toString());
    }
    Collections.sort(converted);

    if (!converted.isEmpty()) {
      if (kind == CLASS || kind == ENUM) {
        builder.append(" implements ");
      } else {
        builder.append(" extends ");
      }
      Joiner.on(", ").appendTo(builder, converted);
    }
    builder.append("\n");
  }

  @Override
  public void appendTo(StringBuilder builder) {
    builder.append(summary);
  }
}
