/*
 * 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;

import com.facebook.buck.event.ThrowableLogEvent;
import com.facebook.buck.java.classes.ClasspathTraversal;
import com.facebook.buck.java.classes.DefaultClasspathTraverser;
import com.facebook.buck.java.classes.FileLike;
import com.facebook.buck.step.AbstractExecutionStep;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.step.Step;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Iterables;
import com.google.common.hash.HashCode;
import com.google.common.hash.Hashing;
import com.google.common.io.ByteStreams;
import com.google.common.io.InputSupplier;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Nullable;

/**
 * {@link Step} that takes a directory or zip of {@code .class} files and traverses it to get the
 * total set of {@code .class} files included by the directory or zip.
 */
public class AccumulateClassNamesStep extends AbstractExecutionStep
    implements Supplier<ImmutableSortedMap<String, HashCode>> {

  /**
   * In the generated {@code classes.txt} file, each line will contain the path to a {@code .class}
   * file (without its suffix) and the SHA-1 hash of its contents, separated by this separator.
   */
  static final String CLASS_NAME_HASH_CODE_SEPARATOR = " ";

  /**
   * Entries in the {@link #pathToJarOrClassesDirectory} that end with this suffix will be written
   * to {@link #whereClassNamesShouldBeWritten}. Since they all share the same suffix, the suffix
   * will be stripped when written to {@link #whereClassNamesShouldBeWritten}.
   */
  private static final String CLASS_NAME_SUFFIX = ".class";

  private final Path pathToJarOrClassesDirectory;
  private final Path whereClassNamesShouldBeWritten;

  /**
   * Map of names of {@code .class} files to hashes of their contents.
   * <p>
   * This is not set until this step is executed.
   */
  @Nullable
  private ImmutableSortedMap<String, HashCode> classNames;

  public AccumulateClassNamesStep(Path pathToJarOrClassesDirectory,
      Path whereClassNamesShouldBeWritten) {
    super("get_class_names " + pathToJarOrClassesDirectory + " > " + whereClassNamesShouldBeWritten);
    this.pathToJarOrClassesDirectory = Preconditions.checkNotNull(pathToJarOrClassesDirectory);
    this.whereClassNamesShouldBeWritten = Preconditions.checkNotNull(whereClassNamesShouldBeWritten);
  }

  @Override
  public int execute(ExecutionContext context) {
    final ImmutableSortedMap.Builder<String, HashCode> classNamesBuilder =
        ImmutableSortedMap.naturalOrder();
    Path path = context.getProjectFilesystem().resolve(pathToJarOrClassesDirectory);
    ClasspathTraversal traversal = new ClasspathTraversal(Collections.singleton(path)) {
      @Override
      public void visit(final FileLike fileLike) throws IOException {
        String name = fileLike.getRelativePath();

        // When traversing a JAR file, it may have resources or directory entries that do not end
        // in .class, which should be ignored.
        if (name.endsWith(CLASS_NAME_SUFFIX)) {
          String key = name.substring(0, name.length() - CLASS_NAME_SUFFIX.length());
          InputSupplier<InputStream> input = new InputSupplier<InputStream>() {
            @Override
            public InputStream getInput() throws IOException {
              return fileLike.getInput();
            }
          };
          HashCode value = ByteStreams.hash(input, Hashing.sha1());
          classNamesBuilder.put(key, value);
        }
      }
    };

    try {
      new DefaultClasspathTraverser().traverse(traversal);
    } catch (IOException e) {
      e.printStackTrace(context.getStdErr());
      return 1;
    }

    ImmutableSortedMap<String, HashCode> classNames = classNamesBuilder.build();
    try {
      context.getProjectFilesystem().writeLinesToPath(
          Iterables.transform(classNames.entrySet(),
              new Function<Map.Entry<String, HashCode>, String>() {
            @Override
            public String apply(Entry<String, HashCode> entry) {
              return entry.getKey() + CLASS_NAME_HASH_CODE_SEPARATOR + entry.getValue();
            }
          }),
          whereClassNamesShouldBeWritten);
    } catch (IOException e) {
      context.getBuckEventBus().post(ThrowableLogEvent.create(e,
          "There was an error writing the list of .class files to %s.",
          whereClassNamesShouldBeWritten));
      return 1;
    }

    this.classNames = classNames;
    return 0;
  }

  @Override
  public ImmutableSortedMap<String, HashCode> get() {
    Preconditions.checkNotNull(classNames,
        "Step must be executed successfully before invoking this method.");
    return classNames;
  }

  @VisibleForTesting
  void setClassNamesForTesting(ImmutableSortedMap<String, HashCode> classNames) {
    this.classNames = classNames;
  }
}
