// Copyright 2024 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.remote.disk;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.jni.JniLoader;
import com.google.devtools.build.lib.vfs.Path;
import java.io.IOException;
import java.util.HashSet;
import javax.annotation.Nullable;

/**
 * A wrapper around the SQLite C API.
 *
 * <p>Exposes only the subset of the SQLite C API required by Bazel.
 */
public final class Sqlite {

  private Sqlite() {}

  public static final int ERR_ERROR = 1;
  public static final int ERR_INTERNAL = 2;
  public static final int ERR_PERM = 3;
  public static final int ERR_ABORT = 4;
  public static final int ERR_BUSY = 5;
  public static final int ERR_LOCKED = 6;
  public static final int ERR_NOMEM = 7;
  public static final int ERR_READONLY = 8;
  public static final int ERR_INTERRUPT = 9;
  public static final int ERR_IOERR = 10;
  public static final int ERR_CORRUPT = 11;
  public static final int ERR_NOTFOUND = 12;
  public static final int ERR_FULL = 13;
  public static final int ERR_CANTOPEN = 14;
  public static final int ERR_PROTOCOL = 15;
  public static final int ERR_EMPTY = 16;
  public static final int ERR_SCHEMA = 17;
  public static final int ERR_TOOBIG = 18;
  public static final int ERR_CONSTRAINT = 19;
  public static final int ERR_MISMATCH = 20;
  public static final int ERR_MISUSE = 21;
  public static final int ERR_NOLFS = 22;
  public static final int ERR_AUTH = 23;
  public static final int ERR_FORMAT = 24;
  public static final int ERR_RANGE = 25;
  public static final int ERR_NOTADB = 26;
  public static final int ERR_NOTICE = 27;
  public static final int ERR_WARNING = 28;

  static {
    JniLoader.loadJni();
  }

  /** An exception thrown when the SQLite C API returns an error. */
  public static final class SqliteException extends IOException {
    private final int code;

    public SqliteException(int code) {
      super(String.format("SQLite error: %s (%d)", errStr(code), code));
      this.code = code;
    }

    /**
     * Returns the SQLite error code.
     *
     * <p>Error codes SQLITE_OK, SQLITE_ROW and SQLITE_DONE never cause an exception to be thrown.
     */
    public int getCode() {
      return code;
    }
  }

  /**
   * Opens a connection to a database, creating it in an empty state if it doesn't yet exist.
   *
   * @param path the path to the database
   * @throws IOException if an error occurred while opening the connection
   */
  public static Connection newConnection(Path path) throws IOException {
    checkNotNull(path);
    return new Connection(path);
  }

  /**
   * A connection to a database.
   *
   * <p>This class is *not* thread-safe. A single connection should be used by a single thread. Use
   * separate connections to the same database for multithreaded access.
   */
  public static final class Connection implements AutoCloseable {

    // C pointer to the `sqlite3` handle. Zero means the connection has been closed.
    private long connPtr;

    // Tracks open statements so they can also be closed when the connection is closed.
    private final HashSet<Statement> openStatements = new HashSet<>();

    private Connection(Path path) throws IOException {
      this.connPtr = openConn(path.getPathString());
    }

    /**
     * Closes the connection, rendering it unusable.
     *
     * <p>As a convenience, every {@link Statement} associated with the connection is also closed,
     * with any errors silently ignored.
     *
     * <p>Multiple calls have no further effect.
     *
     * @throws IOException if an error occurred while closing the connection
     */
    @Override
    public void close() throws IOException {
      if (connPtr != 0) {
        // SQLite won't let us close the connection before first closing associated statements.
        for (Statement stmt : ImmutableList.copyOf(openStatements)) {
          stmt.close();
        }
        closeConn(connPtr);
        connPtr = 0;
      }
    }

    /**
     * Creates a new {@link Statement}.
     *
     * @param sql a string containing a single SQL statement
     * @throws IOException if the string contains multiple SQL statements, or the single SQL
     *     statement could not be parsed and validated
     */
    public Statement newStatement(String sql) throws IOException {
      checkState(connPtr != 0, "newStatement() called in invalid state");
      Statement stmt = new Statement(this, sql);
      openStatements.add(stmt);
      return stmt;
    }

    /**
     * Executes a statement to completion and discards its result.
     *
     * <p>For statements whose result is of interest, or statements that will be executed multiple
     * times, use {@link #newStatement} and {@link Statement#executeQuery}.
     *
     * @throws IOException if the string contains multiple SQL statements; or the single SQL
     *     statement could not be parsed and validated; or an execution error occurred
     */
    public void executeUpdate(String sql) throws IOException {
      try (Statement stmt = new Statement(this, sql)) {
        stmt.executeUpdate();
      }
    }
  }

  /**
   * A prepared statement.
   *
   * <p>Provides a facility to bind values to parameters and execute the statement by calling one of
   * {@link #executeQuery} or {@link #executeUpdate}. The same statement may be executed multiple
   * times, with its parameters possibly bound to different values, but there can be at most one
   * ongoing execution at a time.
   *
   * <p>Parameters that haven't been bound or whose binding has been cleared behave as null.
   */
  public static final class Statement implements AutoCloseable {

    // The connection owning this statement.
    private Connection conn;

    // C pointer to te `sqlite3_stmt` handle. Zero means the statement has been closed.
    private long stmtPtr;

    // The result of current execution, or null if no execution is ongoing.
    @Nullable private Result currentResult;

    private Statement(Connection conn, String sql) throws IOException {
      this.conn = conn;
      stmtPtr = prepareStmt(conn.connPtr, sql);
      if (stmtPtr == -1) {
        // Special value returned when a multi-statement string is detected.
        throw new IOException("unsupported multi-statement string");
      }
    }

    /**
     * Closes the statement, rendering it unusable.
     *
     * <p>A {@link Result} previously returned by {@link #executeQuery} is also closed, with any
     * error silently ignored.
     *
     * <p>Multiple calls have no additional effect.
     */
    @Override
    public void close() {
      if (stmtPtr != 0) {
        if (currentResult != null) {
          try {
            currentResult.close();
          } catch (IOException e) {
            // Intentionally ignored: an error always pertains to a particular execution, and should
            // only be reported when Result#close is called directly.
          }
        }
        try {
          finalizeStmt(stmtPtr);
        } catch (IOException e) {
          // Cannot occur since the statement has been reset by Result#close.
          throw new IllegalStateException("unexpected exception thrown by finalize", e);
        }
        conn.openStatements.remove(this);
        conn = null;
        stmtPtr = 0;
      }
    }

    /**
     * Binds a long value to the statement's i-th parameter, counting from 1.
     *
     * <p>The binding remains in effect until it is cleared or another value is bound to the same
     * parameter.
     *
     * <p>Must not be called after {@link #executeQuery} returns a {@link Result} and before the
     * {@link Result} is closed.
     */
    public void bindLong(int i, long val) throws IOException {
      checkState(stmtPtr != 0 && currentResult == null, "bindLong() called in invalid state");
      bindStmtLong(stmtPtr, i, val);
    }

    /**
     * Binds a double value to the statement's i-th parameter, counting from 1.
     *
     * <p>The binding remains in effect until it is cleared or another value is bound to the same
     * parameter.
     *
     * <p>Must not be called after {@link #executeQuery} returns a {@link Result} and before the
     * {@link Result} is closed.
     */
    public void bindDouble(int i, double val) throws IOException {
      checkState(stmtPtr != 0 && currentResult == null, "bindDouble() called in invalid state");
      bindStmtDouble(stmtPtr, i, val);
    }

    /**
     * Binds a non-null string value to the statement's i-th parameter, counting from 1.
     *
     * <p>The binding remains in effect until it is cleared or another value is bound to the same
     * parameter.
     *
     * <p>Must not be called after {@link #executeQuery} returns a {@link Result} and before the
     * {@link Result} is closed.
     */
    public void bindString(int i, String val) throws IOException {
      checkState(stmtPtr != 0 && currentResult == null, "bindString() called in invalid state");
      checkNotNull(val);
      bindStmtString(stmtPtr, i, val);
    }

    /**
     * Clears the i-th binding.
     *
     * <p>Must not be called after {@link #executeQuery} returns a {@link Result} and before the
     * {@link Result} is closed.
     */
    public void clearBinding(int i) throws IOException {
      checkState(stmtPtr != 0 && currentResult == null, "clearBinding() called in invalid state");
      clearStmtBinding(stmtPtr, i);
    }

    /**
     * Clears all bindings.
     *
     * <p>Must not be called after {@link #executeQuery} returns a {@link Result} and before the
     * {@link Result} is closed.
     */
    public void clearBindings() throws IOException {
      checkState(stmtPtr != 0 && currentResult == null, "clearBindings() called in invalid state");
      clearStmtBindings(stmtPtr);
    }

    /**
     * Executes a statement.
     *
     * <p>Execution doesn't actually start until the first call to {@link Result#next}.
     *
     * <p>Must not be called again until the returned {@link Result} has been closed.
     */
    public Result executeQuery() {
      checkState(stmtPtr != 0 && currentResult == null, "executeQuery() called in invalid state");
      currentResult = new Result(this);
      return currentResult;
    }

    /**
     * Executes a statement to completion and discards its result.
     *
     * <p>For statements whose result is of interest, use {@link #executeQuery}.
     *
     * <p>Must not be called after {@link #executeQuery} until the returned {@link Result} has been
     * closed.
     *
     * @throws IOException if an execution error occurred
     */
    public void executeUpdate() throws IOException {
      checkState(stmtPtr != 0 && currentResult == null, "executeUpdate() called in invalid state");
      currentResult = new Result(this);
      try {
        while (currentResult.next()) {}
      } finally {
        currentResult.close();
      }
    }
  }

  /**
   * The result of executing a statement.
   *
   * <p>Acts as a cursor to iterate over result rows and obtain the corresponding column values. The
   * cursor is initially positioned before the first row. A call to {@link #next} moves the cursor
   * to the next row, returning {@code false} once no more results are available. If a call to
   * {@link #next} returns {@code true}, the getter methods may be called to retrieve the column
   * values for the current row.
   */
  public static final class Result implements AutoCloseable {

    // The statement owning this result.
    private Statement stmt;

    enum State {
      START, // next() not yet called
      CONTINUE, // last call to next() returned true
      DONE, // last call to next() returned false, but close() not yet called
      ERROR, // last call to next() threw, but close() not yet called
      CLOSED // close() was called
    }

    private State state = State.START;

    private Result(Statement stmt) {
      this.stmt = stmt;
    }

    /**
     * Closes the result, rendering it unusable.
     *
     * <p>Multiple calls have no additional effect.
     *
     * @throws IOException if an error occurred while finishing execution
     */
    @Override
    public void close() throws IOException {
      if (state != State.CLOSED) {
        try {
          resetStmt(stmt.stmtPtr);
        } catch (IOException e) {
          // Some statements may throw an error only after the result has been fully consumed.
          // However, if the error has already been thrown by next(), don't throw it again.
          if (state != State.ERROR) {
            throw e;
          }
        } finally {
          stmt.currentResult = null;
          stmt = null;
          state = State.CLOSED;
        }
      }
    }

    /**
     * Advances the cursor the next row.
     *
     * <p>Must not be called further after {@code false} is returned or an exception is thrown.
     *
     * @return whether another row was available
     * @throws IOException if an error occurred while executing the statement
     */
    public boolean next() throws IOException {
      checkState(state == State.START || state == State.CONTINUE, "next() called in invalid state");

      try {
        boolean available = stepStmt(stmt.stmtPtr);
        state = available ? State.CONTINUE : State.DONE;
        return available;
      } catch (IOException e) {
        state = State.ERROR;
        throw e;
      }
    }

    /**
     * Returns whether the i-th column for the current result row is null.
     *
     * <p>WARNING: this must be called before any of the getter methods. Calling a getter method may
     * cause a conversion to occur, after which the return value of this method is unspecified.
     */
    public boolean isNull(int i) throws IOException {
      checkState(state == State.CONTINUE, "isNull() called in invalid state");
      return columnIsNull(stmt.stmtPtr, i);
    }

    /**
     * Reads the i-th column for the current result row, starting from 0, as a long.
     *
     * <p>If the column is not of long type, a conversion occurs. In particular, null is converted
     * to 0.
     *
     * <p>Must not be called unless the last call to {@link #next} returned {@code true}.
     */
    public long getLong(int i) throws IOException {
      checkState(state == State.CONTINUE, "getLong() called in invalid state");
      return columnLong(stmt.stmtPtr, i);
    }

    /**
     * Reads the i-th column for the current result row, starting from 0, as a double.
     *
     * <p>If the column is not of double type, a conversion occurs. In particular, null is converted
     * to 0.0.
     *
     * <p>Must not be called unless the last call to {@link #next} returned {@code true}.
     */
    public double getDouble(int i) throws IOException {
      checkState(state == State.CONTINUE, "getDouble() called in invalid state");
      return columnDouble(stmt.stmtPtr, i);
    }

    /**
     * Reads the i-th column for the current result row, starting from 0, as a string.
     *
     * <p>If the column is not of string type, a conversion occurs. In particular, null is converted
     * to the empty string.
     *
     * <p>Must not be called unless the last call to {@link #next} returned {@code true}.
     */
    public String getString(int i) throws IOException {
      checkState(state == State.CONTINUE, "getString() called in invalid state");
      return columnString(stmt.stmtPtr, i);
    }
  }

  private static native String errStr(int code);

  private static native long openConn(String path) throws IOException;

  private static native void closeConn(long conn) throws IOException;

  private static native long prepareStmt(long conn, String sql) throws IOException;

  private static native void bindStmtLong(long stmt, int i, long value) throws IOException;

  private static native void bindStmtDouble(long stmt, int i, double value) throws IOException;

  private static native void bindStmtString(long stmt, int i, String value) throws IOException;

  private static native void clearStmtBinding(long stmt, int i) throws IOException;

  private static native void clearStmtBindings(long stmt) throws IOException;

  private static native boolean stepStmt(long stmt) throws IOException;

  private static native boolean columnIsNull(long stmt, int i) throws IOException;

  private static native long columnLong(long stmt, int i) throws IOException;

  private static native double columnDouble(long stmt, int i) throws IOException;

  private static native String columnString(long stmt, int i) throws IOException;

  private static native void resetStmt(long stmt) throws IOException;

  private static native void finalizeStmt(long stmt) throws IOException;
}
