/*
 * 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.ThrowableConsoleEvent;
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.java.classes.FileLikes;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.step.Step;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
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.ByteSource;

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

/**
 * {@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 implements Step {

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

  private static final Splitter CLASS_NAME_AND_HASH_SPLITTER = Splitter.on(
      CLASS_NAME_HASH_CODE_SEPARATOR);

  private final Optional<Path> pathToJarOrClassesDirectory;
  private final Path whereClassNamesShouldBeWritten;

  /**
   * @param pathToJarOrClassesDirectory Where to look for .class files. If absent, then an empty
   *     file will be written to {@code whereClassNamesShouldBeWritten}.
   * @param whereClassNamesShouldBeWritten Path to a file where an alphabetically sorted list of
   *     class files and corresponding SHA-1 hashes of their contents will be written.
   */
  public AccumulateClassNamesStep(Optional<Path> pathToJarOrClassesDirectory,
      Path whereClassNamesShouldBeWritten) {
    this.pathToJarOrClassesDirectory = pathToJarOrClassesDirectory;
    this.whereClassNamesShouldBeWritten = whereClassNamesShouldBeWritten;
  }

  @Override
  public int execute(ExecutionContext context) {
    ImmutableSortedMap<String, HashCode> classNames;
    if (pathToJarOrClassesDirectory.isPresent()) {
      Optional<ImmutableSortedMap<String, HashCode>> classNamesOptional = calculateClassHashes(
          context,
          context.getProjectFilesystem().resolve(pathToJarOrClassesDirectory.get()));
      if (classNamesOptional.isPresent()) {
        classNames = classNamesOptional.get();
      } else {
        return 1;
      }
    } else {
      classNames = ImmutableSortedMap.of();
    }

    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(ThrowableConsoleEvent.create(e,
          "There was an error writing the list of .class files to %s.",
          whereClassNamesShouldBeWritten));
      return 1;
    }

    return 0;
  }

  @Override
  public String getShortName() {
    return "get_class_names";
  }

  @Override
  public String getDescription(ExecutionContext context) {
    String sourceString = pathToJarOrClassesDirectory
        .transform(Functions.toStringFunction())
        .or("null");
    return String.format("get_class_names %s > %s",
        sourceString,
        whereClassNamesShouldBeWritten);
  }

  /**
   * @return an Optional that will be absent if there was an error.
   */
  public static Optional<ImmutableSortedMap<String, HashCode>> calculateClassHashes(
      ExecutionContext context, Path path) {
    final ImmutableSortedMap.Builder<String, HashCode> classNamesBuilder =
        ImmutableSortedMap.naturalOrder();
    ClasspathTraversal traversal =
        new ClasspathTraversal(Collections.singleton(path), context.getProjectFilesystem()) {
          @Override
          public void visit(final FileLike fileLike) throws IOException {
            // When traversing a JAR file, it may have resources or directory entries that do not
            // end in .class, which should be ignored.
            if (!FileLikes.isClassFile(fileLike)) {
              return;
            }

            String key = FileLikes.getFileNameWithoutClassSuffix(fileLike);
            ByteSource input = new ByteSource() {
              @Override
              public InputStream openStream() throws IOException {
                return fileLike.getInput();
              }
            };
            HashCode value = input.hash(Hashing.sha1());
            classNamesBuilder.put(key, value);
          }
        };

    try {
      new DefaultClasspathTraverser().traverse(traversal);
    } catch (IOException e) {
      context.logError(e, "Error accumulating class names for %s.", path);
      return Optional.absent();
    }

    return Optional.of(classNamesBuilder.build());
  }

  /**
   * @param lines that were written in the same format output by {@link #execute(ExecutionContext)}.
   */
  public static ImmutableSortedMap<String, HashCode> parseClassHashes(List<String> lines) {
    ImmutableSortedMap.Builder<String, HashCode> classNamesBuilder =
        ImmutableSortedMap.naturalOrder();

    for (String line : lines) {
      List<String> parts = CLASS_NAME_AND_HASH_SPLITTER.splitToList(line);
      Preconditions.checkState(parts.size() == 2);
      String key = parts.get(0);
      HashCode value = HashCode.fromString(parts.get(1));
      classNamesBuilder.put(key, value);
    }

    return classNamesBuilder.build();
  }

}
