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

import com.facebook.buck.event.BuckEventBus;
import com.facebook.buck.event.LogEvent;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.util.BuckConstant;
import com.facebook.buck.util.ProjectFilesystem;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Set;

/**
 * Utility for recording the paths to the output files generated by a build rule, as well as any
 * metadata about those output files. This data will be packaged up into an artifact that will be
 * stored in the cache. The metadata will also be written to disk so it can be read on a subsequent
 * build by a {@link OnDiskBuildInfo}.
 */
public class BuildInfoRecorder {

  private final BuildTarget buildTarget;
  private final Path pathToMetadataDirectory;
  private final ProjectFilesystem projectFilesystem;
  private final Map<String, String> metadataToWrite;
  private final RuleKey ruleKey;

  /**
   * Every value in this set is a path relative to the project root.
   */
  private final Set<Path> pathsToOutputFiles;

  BuildInfoRecorder(BuildTarget buildTarget,
      ProjectFilesystem projectFilesystem,
      RuleKey ruleKey,
      RuleKey rukeKeyWithoutDeps) {
    this.buildTarget = Preconditions.checkNotNull(buildTarget);
    this.pathToMetadataDirectory = BuildInfo.getPathToMetadataDirectory(buildTarget);
    this.projectFilesystem = Preconditions.checkNotNull(projectFilesystem);
    this.metadataToWrite = Maps.newHashMap();

    metadataToWrite.put(BuildInfo.METADATA_KEY_FOR_RULE_KEY,
        Preconditions.checkNotNull(ruleKey).toString());
    metadataToWrite.put(BuildInfo.METADATA_KEY_FOR_RULE_KEY_WITHOUT_DEPS,
        Preconditions.checkNotNull(rukeKeyWithoutDeps).toString());
    this.ruleKey = ruleKey;
    this.pathsToOutputFiles = Sets.newHashSet();
  }

  /**
   * Writes the metadata currently stored in memory to the directory returned by
   * {@link BuildInfo#getPathToMetadataDirectory(BuildTarget)}.
   */
  public void writeMetadataToDisk() throws IOException {
    projectFilesystem.rmdir(pathToMetadataDirectory.toString());
    projectFilesystem.mkdirs(pathToMetadataDirectory);

    for (Map.Entry<String, String> entry : metadataToWrite.entrySet()) {
      projectFilesystem.writeContentsToPath(
          entry.getValue(),
          pathToMetadataDirectory.resolve(entry.getKey()));
    }
  }

  /**
   * This key/value pair is stored in memory until {@link #writeMetadataToDisk()} is invoked.
   */
  public void addMetadata(String key, String value) {
    metadataToWrite.put(Preconditions.checkNotNull(key), Preconditions.checkNotNull(value));
  }

  /**
   * Creates a zip file of the metadata and recorded artifacts and stores it in the artifact cache.
   */
  public void performUploadToArtifactCache(ArtifactCache artifactCache, BuckEventBus eventBus) {
    // TODO(mbolin): Skip all of this if caching is disabled. Although artifactCache.store() will be
    // a noop, building up the zip is wasted I/O.
    ImmutableSet<Path> pathsToIncludeInZip = ImmutableSet.<Path>builder()
        .addAll(Iterables.transform(metadataToWrite.keySet(),
            new Function<String, Path>() {
              @Override
              public Path apply(String key) {
                return pathToMetadataDirectory.resolve(key);
              }
            }))
        .addAll(pathsToOutputFiles)
        .build();
    File zip;
    try {
      zip = File.createTempFile(buildTarget.getFullyQualifiedName().replace('/', '_'), ".zip");
      projectFilesystem.createZip(pathsToIncludeInZip, zip);
    } catch (IOException e) {
      eventBus.post(LogEvent.info("Failed to create zip for %s containing:\n%s",
          buildTarget,
          Joiner.on('\n').join(ImmutableSortedSet.copyOf(pathsToIncludeInZip))));
      e.printStackTrace();
      return;
    }
    artifactCache.store(ruleKey, zip);
    zip.delete();
  }

  /**
   * Fetches the artifact associated with the {@link #buildTarget} for this class and writes it to
   * the specified {@code outputFile}.
   */
  public CacheResult fetchArtifactForBuildable(File outputFile, ArtifactCache artifactCache) {
    Preconditions.checkNotNull(outputFile);
    return artifactCache.fetch(ruleKey, outputFile);
  }

  /**
   * @param pathToArtifact Must be relative to the directory where the Buildable's
   *     generated files are to be written. The caller should not be concerned with the location
   *     of this directory.
   */
  public void recordArtifact(Path pathToArtifact) {
    Preconditions.checkNotNull(pathToArtifact);
    Path fullPath = Paths.get(BuckConstant.GEN_DIR, buildTarget.getBasePath(),
        pathToArtifact.toString());
    pathsToOutputFiles.add(fullPath);
  }
}
