// 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.Spawn;
import com.google.devtools.build.lib.actions.SpawnResult;
import com.google.devtools.build.lib.exec.SpawnRunner.SpawnExecutionContext;
import java.io.Closeable;
import java.io.IOException;
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) 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) throws InterruptedException, IOException {
        throw new IllegalStateException();
      }

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

  /** A no-op spawn cache. */
  public static class NoSpawnCache implements SpawnCache {
    @Override
    public CacheHandle lookup(Spawn spawn, SpawnExecutionContext 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) throws ExecException, 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 SpawnExecutionContext#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>The lookup must not succeed for non-cachable spawns. See {@link Spawns#mayBeCached()} and
   * {@link Spawns#mayBeCachedRemotely}.
   *
   * <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, SpawnExecutionContext context)
      throws ExecException, IOException, InterruptedException;
}
