// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "impeller/archivist/archive_database.h"

#include "third_party/sqlite/sqlite3.h"

#include <sstream>
#include <string>

#include "impeller/archivist/archive.h"
#include "impeller/archivist/archive_class_registration.h"
#include "impeller/archivist/archive_statement.h"
#include "impeller/base/validation.h"

namespace impeller {

struct ArchiveDatabase::Handle {
  explicit Handle(const std::string& filename) {
    if (::sqlite3_initialize() != SQLITE_OK) {
      VALIDATION_LOG << "Could not initialize sqlite.";
      return;
    }

    sqlite3* db = nullptr;
    auto res = ::sqlite3_open(filename.c_str(), &db);

    if (res != SQLITE_OK || db == nullptr) {
      return;
    }

    handle_ = db;
  }

  ~Handle() {
    if (handle_ == nullptr) {
      return;
    }
    ::sqlite3_close(handle_);
  }

  ::sqlite3* Get() const { return handle_; }

  bool IsValid() const { return handle_ != nullptr; }

 private:
  ::sqlite3* handle_ = nullptr;

  FML_DISALLOW_COPY_AND_ASSIGN(Handle);
};

ArchiveDatabase::ArchiveDatabase(const std::string& filename)
    : handle_(std::make_unique<Handle>(filename)) {
  if (!handle_->IsValid()) {
    handle_.reset();
    return;
  }

  begin_transaction_stmt_ = std::unique_ptr<ArchiveStatement>(
      new ArchiveStatement(handle_->Get(), "BEGIN TRANSACTION;"));

  if (!begin_transaction_stmt_->IsValid()) {
    return;
  }

  end_transaction_stmt_ = std::unique_ptr<ArchiveStatement>(
      new ArchiveStatement(handle_->Get(), "END TRANSACTION;"));

  if (!end_transaction_stmt_->IsValid()) {
    return;
  }

  rollback_transaction_stmt_ = std::unique_ptr<ArchiveStatement>(
      new ArchiveStatement(handle_->Get(), "ROLLBACK TRANSACTION;"));

  if (!rollback_transaction_stmt_->IsValid()) {
    return;
  }
}

ArchiveDatabase::~ArchiveDatabase() = default;

bool ArchiveDatabase::IsValid() const {
  return handle_ != nullptr;
}

int64_t ArchiveDatabase::GetLastInsertRowID() {
  if (!IsValid()) {
    return 0u;
  }
  return ::sqlite3_last_insert_rowid(handle_->Get());
}

static inline const ArchiveClassRegistration* RegistrationIfReady(
    const ArchiveClassRegistration* registration) {
  if (registration == nullptr) {
    return nullptr;
  }
  return registration->IsValid() ? registration : nullptr;
}

const ArchiveClassRegistration* ArchiveDatabase::GetRegistrationForDefinition(
    const ArchiveDef& definition) {
  auto found = registrations_.find(definition.table_name);
  if (found != registrations_.end()) {
    /*
     *  This class has already been registered.
     */
    return RegistrationIfReady(found->second.get());
  }

  /*
   *  Initialize a new class registration for the given class definition.
   */
  auto registration = std::unique_ptr<ArchiveClassRegistration>(
      new ArchiveClassRegistration(*this, definition));
  auto res =
      registrations_.emplace(definition.table_name, std::move(registration));

  /*
   *  If the new class registration is ready, return it to the caller.
   */
  return res.second ? RegistrationIfReady((*(res.first)).second.get())
                    : nullptr;
}

ArchiveStatement ArchiveDatabase::CreateStatement(
    const std::string& statementString) const {
  return ArchiveStatement{handle_ ? handle_->Get() : nullptr, statementString};
}

ArchiveTransaction ArchiveDatabase::CreateTransaction(
    int64_t& transactionCount) {
  return ArchiveTransaction{transactionCount,          //
                            *begin_transaction_stmt_,  //
                            *end_transaction_stmt_,    //
                            *rollback_transaction_stmt_};
}

}  // namespace impeller
