// Copyright 2014 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.analysis;

import static com.google.common.base.Preconditions.checkArgument;

import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.starlarkbuildapi.FilesToRunProviderApi;
import javax.annotation.Nullable;

/** Returns information about executables produced by a target and the files needed to run it. */
@Immutable
public class FilesToRunProvider implements TransitiveInfoProvider, FilesToRunProviderApi<Artifact> {

  /** The name of the field in Starlark used to access a {@link FilesToRunProvider}. */
  public static final String STARLARK_NAME = "files_to_run";

  public static final FilesToRunProvider EMPTY =
      new FilesToRunProvider(NestedSetBuilder.emptySet(Order.STABLE_ORDER));

  public static FilesToRunProvider create(
      NestedSet<Artifact> filesToRun,
      @Nullable RunfilesSupport runfilesSupport,
      @Nullable Artifact executable) {
    if (filesToRun.isEmpty()) {
      checkArgument(runfilesSupport == null, "No files to run with runfiles: %s", runfilesSupport);
      checkArgument(executable == null, "No files to run with executable: %s", executable);
      return EMPTY;
    }
    if (runfilesSupport == null && executable == null) {
      return new FilesToRunProvider(filesToRun);
    }
    if (filesToRun.isSingleton()
        && runfilesSupport == null
        && filesToRun.getSingleton().equals(executable)) {
      return new SingleExecutableFilesToRunProvider(filesToRun);
    }
    return new FullFilesToRunProvider(filesToRun, runfilesSupport, executable);
  }

  private final NestedSet<Artifact> filesToRun;

  private FilesToRunProvider(NestedSet<Artifact> filesToRun) {
    this.filesToRun = filesToRun;
  }

  @Override
  public final boolean isImmutable() {
    return true; // immutable and Starlark-hashable
  }

  /**
   * Returns artifacts needed to run the executable for this target.
   *
   * <p>This method should not be used because its semantics are complicated and confusing. Instead,
   * either use {@link #getExecutable()} or {@link #getRunfilesSupport()} if you know what you are
   * doing and it's something very arcane.
   */
  @Deprecated
  public final NestedSet<Artifact> getFilesToRun() {
    return filesToRun;
  }

  @Override
  @Nullable
  public Artifact getExecutable() {
    return null;
  }

  /**
   * Returns the {@link RunfilesSupport} object associated with the target or null if it does not
   * exist.
   */
  @Nullable
  public RunfilesSupport getRunfilesSupport() {
    return null;
  }

  @Override
  @Nullable
  public final Artifact getRunfilesManifest() {
    var runfilesSupport = getRunfilesSupport();
    return runfilesSupport != null ? runfilesSupport.getRunfilesManifest() : null;
  }

  @Nullable
  @Override
  public Artifact getRepoMappingManifest() {
    var runfilesSupport = getRunfilesSupport();
    return runfilesSupport != null ? runfilesSupport.getRepoMappingManifest() : null;
  }

  /** A single executable. */
  private static final class SingleExecutableFilesToRunProvider extends FilesToRunProvider {

    private SingleExecutableFilesToRunProvider(NestedSet<Artifact> filesToRun) {
      super(filesToRun);
    }

    @Override
    public Artifact getExecutable() {
      return getFilesToRun().getSingleton();
    }
  }

  /** A {@link FilesToRunProvider} possible with {@link RunfilesSupport} and/or an executable. */
  private static final class FullFilesToRunProvider extends FilesToRunProvider {
    @Nullable private final RunfilesSupport runfilesSupport;
    @Nullable private final Artifact executable;

    private FullFilesToRunProvider(
        NestedSet<Artifact> filesToRun,
        @Nullable RunfilesSupport runfilesSupport,
        @Nullable Artifact executable) {
      super(filesToRun);
      this.runfilesSupport = runfilesSupport;
      this.executable = executable;
    }

    @Override
    @Nullable
    public RunfilesSupport getRunfilesSupport() {
      return runfilesSupport;
    }

    @Override
    @Nullable
    public Artifact getExecutable() {
      return executable;
    }
  }
}
