/*
 * 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.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.ByteStreams;
import com.google.common.io.Files;
import com.google.common.io.InputSupplier;

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

public class DefaultFileHashCache implements FileHashCache {

  private final ProjectFilesystem projectFilesystem;
  private Console console;

  @VisibleForTesting
  final LoadingCache<Path, HashCode> loadingCache;

  public DefaultFileHashCache(ProjectFilesystem projectFilesystem, Console console) {
    this.projectFilesystem = Preconditions.checkNotNull(projectFilesystem);
    this.console = Preconditions.checkNotNull(console);

    this.loadingCache = CacheBuilder.newBuilder()
        .build(new CacheLoader<Path, HashCode>() {
          @Override
          public HashCode load(Path path) throws Exception {
            File file = DefaultFileHashCache.this.projectFilesystem.resolve(path).toFile();
            InputSupplier<? extends InputStream> inputSupplier = Files.newInputStreamSupplier(file);
            return ByteStreams.hash(inputSupplier, Hashing.sha1());
          }
        });
  }

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

  /**
   * @param path {@link #contains(java.nio.file.Path)} must be true for path.
   * @return The {@link com.google.common.hash.HashCode} of the contents of path.
   */
  @Override
  public HashCode get(Path path) {
    HashCode sha1;
    try {
      sha1 = loadingCache.get(path.normalize());
    } catch (ExecutionException 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.
   */
  @Subscribe
  public synchronized void onFileSystemChange(WatchEvent<?> event) throws IOException {
    if (console.getVerbosity() == Verbosity.ALL) {
      console.getStdErr().printf("DefaultFileHashCache watched event %s %s\n", event.kind(),
          projectFilesystem.createContextString(event));
    }

    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();
      loadingCache.invalidate(path.normalize());
    } else {
      // Non-path change event, likely an overflow due to many change events: invalidate everything.
      loadingCache.invalidateAll();
    }
  }

  /**
   * DefaultFileHashCaches may be reused on different consoles, so allow the console to be set.
   * @param console The new console that the Parser should use.
   */
  public synchronized void setConsole(Console console) {
    this.console = console;
  }
}
