// Copyright 2016 The Bazel Authors. All rights reserved.
//
// 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.google.devtools.bazel.e4b.command;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Objects;

import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

/**
 * A parsed version of the JSON files returned by the application of the IDE build information
 * aspect.
 */
public final class IdeBuildInfo {

  /**
   * A structure containing the list of jar files generated by a target (interface, class and source
   * jars).
   */
  public static final class Jars {
    private final String ijar; // interface_jar
    private final String jar; // jar
    private final String srcjar; // source_jar

    Jars(JSONObject obj) {
      this.ijar = obj.has("interface_jar") ? obj.getString("interface_jar") : null;
      this.jar = obj.getString("jar");
      this.srcjar = obj.has("srcjar") ? obj.getString("srcjar") : null;
    }

    @Override
    public int hashCode() {
      return Objects.hash(ijar, jar, srcjar);
    }

    public String getInterfaceJar() {
      return ijar;
    }

    public String getJar() {
      return jar;
    }

    public String getSrcJar() {
      return srcjar;
    }
  }

  private final String location; // build_file_artifact_location
  private final ImmutableList<String> deps; // dependencies
  private final String kind; // kind
  private final String label; // label

  private final ImmutableList<Jars> generatedJars; // generated_jars
  private final ImmutableList<Jars> jars; // jars
  private final ImmutableList<String> sources; // sources

  /**
   * Construct an {@link IdeBuildInfo} object from a {@link JSONObject}.
   */
  IdeBuildInfo(JSONObject object) {
    jars = jsonToJarArray(object.getJSONArray("jars"));
    generatedJars = jsonToJarArray(object.getJSONArray("generated_jars"));
    location = object.getString("build_file_artifact_location");
    kind = object.getString("kind");
    label = object.getString("label");
    this.deps = jsonToStringArray(object.getJSONArray("dependencies"));
    this.sources = jsonToStringArray(object.getJSONArray("sources"));
  }

  /**
   * Constructs a map of label -> {@link IdeBuildInfo} from a list of files, parsing each files into
   * a {@link JSONObject} and then converting that {@link JSONObject} to an {@link IdeBuildInfo}
   * object.
   */
  static ImmutableMap<String, IdeBuildInfo> getInfo(List<String> files)
      throws IOException, InterruptedException {
    ImmutableMap.Builder<String, IdeBuildInfo> infos = ImmutableMap.builder();
    for (String s : files) {
      if (!s.isEmpty()) {
        IdeBuildInfo buildInfo =
            new IdeBuildInfo(new JSONObject(new JSONTokener(new FileInputStream(s))));
        infos.put(buildInfo.label, buildInfo);
      }
    }
    return infos.build();
  }

  private ImmutableList<Jars> jsonToJarArray(JSONArray array) {
    ImmutableList.Builder<Jars> builder = ImmutableList.builder();
    for (Object o : array) {
      builder.add(new Jars((JSONObject) o));
    }
    return builder.build();
  }

  private ImmutableList<String> jsonToStringArray(JSONArray array) {
    ImmutableList.Builder<String> builder = ImmutableList.builder();
    for (Object o : array) {
      builder.add(o.toString());
    }
    return builder.build();
  }

  /**
   * Location of the target (build file).
   */
  public String getLocation() {
    return location;
  }

  /**
   * List of dependencies of the target.
   */
  public ImmutableList<String> getDeps() {
    return deps;
  }

  /**
   * Kind of the target (e.g., java_test or java_binary).
   */
  public String getKind() {
    return kind;
  }

  /**
   * Label of the target.
   */
  public String getLabel() {
    return label;
  }

  /**
   * List of jars generated by annotations processors when building this target.
   */
  public ImmutableList<Jars> getGeneratedJars() {
    return generatedJars;
  }

  /**
   * List of jars generated by building this target.
   */
  public ImmutableList<Jars> getJars() {
    return jars;
  }

  /**
   * List of sources consumed by this target.
   */
  public ImmutableList<String> getSources() {
    return sources;
  }
}
