// 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.skyframe;

import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.skyframe.serialization.VisibleForSerialization;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationConstant;
import com.google.devtools.build.lib.vfs.Root;
import com.google.devtools.build.skyframe.NotComparableSkyValue;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.errorprone.annotations.FormatMethod;
import java.util.Objects;
import javax.annotation.Nullable;
import net.starlark.java.syntax.Program;

/**
 * The result of BzlCompileFunction, which compiles a .bzl file. There are two subclasses: {@code
 * Success}, for when the file is compiled successfully, and {@code Failure}, for when the file does
 * not exist, or had parser/resolver errors.
 */
// In practice, almost any change to a .bzl causes the BzlCompileValue to be recomputed.
// We could do better with a finer-grained notion of equality than "the source
// files differ". In particular, a trivial change such as fixing a typo in a comment should not
// cause invalidation. (Changes that are only slightly more substantial may be semantically
// significant. For example, inserting a blank line affects subsequent line numbers, which appear
// in error messages and query output.)
//
// Comparing syntax trees for equality is complex and expensive, so the most practical
// implementation of this optimization will have to wait until Starlark files are compiled,
// at which point byte-equality of the compiled representation (which is simple to compute)
// will serve.
//
// TODO(adonovan): actually compile the code. The name is a step ahead of the implementation.
public abstract class BzlCompileValue implements NotComparableSkyValue {

  public abstract boolean lookupSuccessful();

  public abstract Program getProgram(); // on success

  public abstract byte[] getDigest(); // on success

  public abstract String getError(); // on failure

  /** If the file is compiled successfully, this class encapsulates the compiled program. */
  @VisibleForSerialization
  public static class Success extends BzlCompileValue {
    private final Program prog;
    private final byte[] digest;

    private Success(Program prog, byte[] digest) {
      this.prog = Preconditions.checkNotNull(prog);
      this.digest = Preconditions.checkNotNull(digest);
    }

    @Override
    public boolean lookupSuccessful() {
      return true;
    }

    @Override
    public Program getProgram() {
      return this.prog;
    }

    @Override
    public byte[] getDigest() {
      return this.digest;
    }

    @Override
    public String getError() {
      throw new IllegalStateException(
          "attempted to retrieve unsuccessful lookup reason for successful lookup");
    }
  }

  /** If the file isn't found or has errors, this class encapsulates a message with the reason. */
  @VisibleForSerialization
  public static class Failure extends BzlCompileValue {
    private final String errorMsg;

    private Failure(String errorMsg) {
      this.errorMsg = Preconditions.checkNotNull(errorMsg);
    }

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

    @Override
    public Program getProgram() {
      throw new IllegalStateException(
          "attempted to retrieve .bzl program from an unsuccessful lookup");
    }

    @Override
    public byte[] getDigest() {
      throw new IllegalStateException("attempted to retrieve digest for unsuccessful lookup");
    }

    @Override
    public String getError() {
      return this.errorMsg;
    }
  }

  /** Constructs a value from a failure before parsing a file. */
  @FormatMethod
  static BzlCompileValue noFile(String format, Object... args) {
    return new Failure(String.format(format, args));
  }

  /** Constructs a value from a compiled .bzl program. */
  public static BzlCompileValue withProgram(Program prog, byte[] digest) {
    return new Success(prog, digest);
  }

  /** Types of bzl files we may encounter. */
  enum Kind {
    /** A regular .bzl file loaded on behalf of a BUILD or WORKSPACE file. */
    // The reason we can share a single key type for these environments is that they have the same
    // symbol names, even though their symbol definitions (particularly for the "native" object)
    // differ. (See also #11954, which aims to make even the symbol definitions the same.)
    NORMAL,

    /** A .bzl file loaded during evaluation of the {@code @_builtins} pseudo-repository. */
    BUILTINS,

    /** The prelude file, whose declarations are implicitly loaded by all BUILD files. */
    PRELUDE,

    /**
     * A virtual empty file that does not correspond to a lookup in the filesystem. This is used for
     * the default prelude contents, when the real prelude's contents should be ignored (in
     * particular, when its package is missing).
     */
    EMPTY_PRELUDE,
  }

  /** SkyKey for retrieving a compiled .bzl program. */
  @AutoCodec
  public static class Key implements SkyKey {
    private static final SkyKeyInterner<Key> interner = SkyKey.newInterner();

    /** The root in which the .bzl file is to be found. Null for EMPTY_PRELUDE. */
    @Nullable final Root root;

    /** The label of the .bzl to be retrieved. Null for EMPTY_PRELUDE. */
    @Nullable final Label label;

    final Kind kind;

    private Key(Root root, Label label, Kind kind) {
      this.root = root;
      this.label = label;
      this.kind = Preconditions.checkNotNull(kind);
      if (kind != Kind.EMPTY_PRELUDE) {
        Preconditions.checkNotNull(root);
        Preconditions.checkNotNull(label);
      }
    }

    @VisibleForSerialization
    @AutoCodec.Instantiator
    static Key create(Root root, Label label, Kind kind) {
      return interner.intern(new Key(root, label, kind));
    }

    /** Returns whether this key is for a {@code @_builtins} .bzl file. */
    public boolean isBuiltins() {
      return kind == Kind.BUILTINS;
    }

    /** Returns true if the requested file follows the .scl dialect. */
    // See comment in BzlLoadValue#isSclDialect about distinguishing .scl keys by label as opposed
    // to by Kind.
    final boolean isSclDialect() {
      return label != null && label.getName().endsWith(".scl");
    }

    boolean isBuildPrelude() {
      return kind == Kind.PRELUDE || kind == Kind.EMPTY_PRELUDE;
    }

    public Label getLabel() {
      return label;
    }

    @Override
    public int hashCode() {
      return Objects.hash(Key.class, root, label, kind);
    }

    @Override
    public boolean equals(Object other) {
      if (this == other) {
        return true;
      }
      if (other instanceof Key) {
        Key that = (Key) other;
        // Compare roots last since that's the more expensive step.
        return this.kind == that.kind
            && Objects.equals(this.label, that.label)
            && Objects.equals(this.root, that.root);
      }
      return false;
    }

    @Override
    public SkyFunctionName functionName() {
      return SkyFunctions.BZL_COMPILE;
    }

    @Override
    public String toString() {
      return String.format("%s:[%s]%s", functionName(), root, label);
    }

    @Override
    public SkyKeyInterner<Key> getSkyKeyInterner() {
      return interner;
    }
  }

  /** Constructs a key for loading a regular (non-prelude) .bzl. */
  public static Key key(Root root, Label label) {
    return Key.create(root, label, Kind.NORMAL);
  }

  /** Constructs a key for loading a builtins .bzl. */
  public static Key keyForBuiltins(Root root, Label label) {
    return Key.create(root, label, Kind.BUILTINS);
  }

  /** Constructs a key for loading the prelude .bzl. */
  static Key keyForBuildPrelude(Root root, Label label) {
    return Key.create(root, label, Kind.PRELUDE);
  }

  /** The unique SkyKey of EMPTY_PRELUDE kind. */
  @SerializationConstant
  static final Key EMPTY_PRELUDE_KEY = new Key(/*root=*/ null, /*label=*/ null, Kind.EMPTY_PRELUDE);
}
