/*
 * Copyright 2012-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.util;

import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.log.Logger;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.eventbus.Subscribe;
import com.google.common.hash.HashCode;
import com.google.common.hash.Hashing;
import com.google.common.io.ByteSource;
import com.google.common.io.Files;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.util.concurrent.ExecutionException;

public class DefaultFileHashCache implements FileHashCache {

  private static final Logger LOG = Logger.get(DefaultFileHashCache.class);

  private final ProjectFilesystem projectFilesystem;

  @VisibleForTesting
  final LoadingCache<Path, HashCode> loadingCache;

  public DefaultFileHashCache(ProjectFilesystem projectFilesystem) {
    this.projectFilesystem = projectFilesystem;

    this.loadingCache = CacheBuilder.newBuilder()
        .build(new CacheLoader<Path, HashCode>() {
          @Override
          public HashCode load(Path path) throws Exception {
            return getHashCode(path);
          }
        });
  }

  private HashCode getHashCode(Path path) throws IOException {
    // TODO(simons): Should be this.projectFilesystem.computeSha1(path);
    File file = this.projectFilesystem.resolve(path).toFile();
    ByteSource source = Files.asByteSource(file);
    return source.hash(Hashing.sha1());
  }

  @Override
  public boolean contains(Path path) {
    return loadingCache.getIfPresent(path) != null;
  }

  /**
   * @return The {@link com.google.common.hash.HashCode} of the contents of path.
   */
  @Override
  public HashCode get(Path path) {
    HashCode sha1;
    try {
      // Ignored paths will not generate file change events and so are not invalidated correctly.
      // Where ignored paths are output files, they are generated by each build and will not
      // generate cache hits so not caching them is likely a performance win in any case.
      if (projectFilesystem.isIgnored(path)) {
        sha1 = getHashCode(path);
      } else {
        sha1 = loadingCache.get(path.normalize());
      }
    } catch (ExecutionException | IOException e) {
      throw new RuntimeException(e);
    }
    return Preconditions.checkNotNull(sha1, "Failed to find a HashCode for %s.", path);
  }

  /**
   * Called when file change events are posted to the file change EventBus to invalidate cached
   * build rules if required. {@link Path}s contained within events must all be relative to the
   * {@link ProjectFilesystem} root.
   */
  @Subscribe
  public synchronized void onFileSystemChange(WatchEvent<?> event) throws IOException {
    if (projectFilesystem.isPathChangeEvent(event)) {
      // Path event, remove the path from the cache as it has been changed, added or deleted.
      Path path = ((Path) event.context()).normalize();
      LOG.verbose("Invalidating %s", path);
      loadingCache.invalidate(path);
    } else {
      // Non-path change event, likely an overflow due to many change events: invalidate everything.
      LOG.debug("Invalidating all");
      loadingCache.invalidateAll();
    }
  }

}
