// Copyright 2017 The Bazel Authors. All rights reserved.
//
// 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.google.devtools.build.lib.exec;

import com.google.devtools.build.lib.actions.ActionContext;
import com.google.devtools.build.lib.actions.ExecException;
import com.google.devtools.build.lib.actions.ExecutionStrategy;
import com.google.devtools.build.lib.actions.Spawn;
import com.google.devtools.build.lib.actions.SpawnResult;
import com.google.devtools.build.lib.exec.SpawnRunner.SpawnExecutionPolicy;
import com.google.devtools.build.lib.vfs.Path;
import java.io.Closeable;
import java.io.IOException;
import java.util.Collection;
import java.util.NoSuchElementException;

/**
 * A cache that can lookup a {@link SpawnResult} given a {@link Spawn}, and can also upload the
 * results of an executed spawn to the cache.
 *
 * <p>This is an experimental interface to implement caching with sandboxed local execution.
 */
public interface SpawnCache extends ActionContext {
  /** A no-op implementation that has no result, and performs no upload. */
  public static CacheHandle NO_RESULT_NO_STORE = new CacheHandle() {
    @Override
    public boolean hasResult() {
      return false;
    }

    @Override
    public SpawnResult getResult() {
      throw new NoSuchElementException();
    }

    @Override
    public boolean willStore() {
      return false;
    }

    @Override
    public void store(SpawnResult result, Collection<Path> files)
        throws InterruptedException, IOException {
      // Do nothing.
    }

    @Override
    public void close() {
    }
  };

  /**
   * Helper method to create a {@link CacheHandle} from a successful {@link SpawnResult} instance.
   */
  public static CacheHandle success(final SpawnResult result) {
    return new CacheHandle() {
      @Override
      public boolean hasResult() {
        return true;
      }

      @Override
      public SpawnResult getResult() {
        return result;
      }

      @Override
      public boolean willStore() {
        return false;
      }

      @Override
      public void store(SpawnResult result, Collection<Path> files)
          throws InterruptedException, IOException {
        throw new IllegalStateException();
      }

      @Override
      public void close() {
      }
    };
  }

  /** A no-op spawn cache. */
  @ExecutionStrategy(
      name = {"no-cache"},
      contextType = SpawnCache.class
  )
  public static class NoSpawnCache implements SpawnCache {
    @Override
    public CacheHandle lookup(Spawn spawn, SpawnExecutionPolicy context) {
      return SpawnCache.NO_RESULT_NO_STORE;
    }
  }

  /** A no-op implementation that has no results and performs no stores. */
  public static SpawnCache NO_CACHE = new NoSpawnCache();

  /**
   * This object represents both a successful and an unsuccessful cache lookup. If
   * {@link #hasResult} returns true, then {@link #getResult} must successfully return a non-null
   * instance (use the {@link #success} helper method). Otherwise {@link #getResult} should throw an
   * {@link IllegalStateException}.
   *
   * <p>If {@link #hasResult} returns false, then {@link #store} may upload the result to the cache
   * after successful execution.
   *
   * <p>Note that this interface extends {@link Closeable}, and callers must guarantee that
   * {@link #close} is called on this entry (e.g., by using try-with-resources) to free up any
   * acquired resources.
   */
  interface CacheHandle extends Closeable {
    /** Returns whether the cache lookup was successful. */
    boolean hasResult();

    /**
     * Returns the cached result.
     *
     * @throws NoSuchElementException if there is no result in this cache entry
     */
    SpawnResult getResult();

    /**
     * Returns true if the store call will actually do work. Use this to avoid unnecessary work
     * before store if it won't do anything.
     */
    boolean willStore();

    /**
     * Called after successful {@link Spawn} execution, which may or may not store the result in the
     * cache.
     *
     * <p>A cache may silently return from a failed store operation. We recommend to err on the side
     * of raising an exception rather than returning silently, and to offer command-line flags to
     * tweak this default policy as needed.
     *
     * <p>If the current thread is interrupted, then this method should return as quickly as
     * possible with an {@link InterruptedException}.
     */
    void store(SpawnResult result, Collection<Path> files)
        throws InterruptedException, IOException;
  }

  /**
   * Perform a spawn lookup. This method is similar to {@link SpawnRunner#exec}, taking the same
   * parameters and being allowed to throw the same exceptions. The intent for this method is to
   * compute a cache lookup key for the given spawn, looking it up in an implementation-dependent
   * cache (can be either on the local or remote machine), and returning a non-null
   * {@link CacheHandle} instance.
   *
   * <p>If the lookup was successful, this method should write the cached outputs to their
   * corresponding output locations in the output tree, as well as stdout and stderr, after
   * notifying {@link SpawnExecutionPolicy#lockOutputFiles}.
   *
   * <p>If the lookup was unsuccessful, this method can return a {@link CacheHandle} instance that
   * has no result, but uploads the results of the execution to the cache. The reason for a callback
   * object is for the cache to store expensive intermediate values (such as the cache key) that are
   * needed both for the lookup and the subsequent store operation.
   *
   * <p>Note that cache stores may be disabled, in which case the returned {@link CacheHandle}
   * instance's {@link CacheHandle#store} is a no-op.
   */
  CacheHandle lookup(Spawn spawn, SpawnExecutionPolicy context)
      throws ExecException, IOException, InterruptedException;
}
