// Copyright 2018 The Fuchsia 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 "peridot/bin/sessionmgr/storage/session_storage.h"

#include <lib/fidl/cpp/clone.h>
#include <zircon/status.h>

#include <unordered_set>

#include "fuchsia/ledger/cpp/fidl.h"
#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
#include "peridot/bin/sessionmgr/storage/session_storage_xdr.h"
#include "peridot/lib/fidl/clone.h"
#include "peridot/lib/ledger_client/operations.h"
#include "src/lib/uuid/uuid.h"

namespace modular {

SessionStorage::SessionStorage(LedgerClient* ledger_client, LedgerPageId page_id)
    : PageClient("SessionStorage", ledger_client, page_id, kStoryKeyPrefix),
      ledger_client_(ledger_client) {
  FXL_DCHECK(ledger_client_ != nullptr);
}

namespace {

// TODO(rosswang): replace with |std::string::starts_with| after C++20
bool StartsWith(const std::string& string, const std::string& prefix) {
  return string.compare(0, prefix.size(), prefix) == 0;
}

std::string StoryNameToStoryDataKey(fidl::StringPtr story_name) {
  // Not escaped, because only one component after the prefix.
  return kStoryDataKeyPrefix + story_name.value_or("");
}

std::string StoryNameFromStoryDataKey(fidl::StringPtr key) {
  return key->substr(sizeof(kStoryDataKeyPrefix) - 1);
}

std::string StoryNameToStorySnapshotKey(fidl::StringPtr story_name) {
  // Not escaped, because only one component after the prefix.
  return kStorySnapshotKeyPrefix + story_name.value_or("");
}

std::unique_ptr<OperationBase> MakeGetStoryDataCall(
    fuchsia::ledger::Page* const page, fidl::StringPtr story_name,
    fit::function<void(fuchsia::modular::internal::StoryDataPtr)> result_call) {
  return std::make_unique<ReadDataCall<fuchsia::modular::internal::StoryData>>(
      page, StoryNameToStoryDataKey(story_name), true /* not_found_is_ok */, XdrStoryData,
      std::move(result_call));
};

std::unique_ptr<OperationBase> MakeWriteStoryDataCall(
    fuchsia::ledger::Page* const page, fuchsia::modular::internal::StoryDataPtr story_data,
    fit::function<void()> result_call) {
  return std::make_unique<WriteDataCall<fuchsia::modular::internal::StoryData>>(
      page, StoryNameToStoryDataKey(story_data->story_info().id), XdrStoryData,
      std::move(story_data), std::move(result_call));
};

class CreateStoryCall : public LedgerOperation<fidl::StringPtr, fuchsia::ledger::PageId> {
 public:
  CreateStoryCall(fuchsia::ledger::Ledger* const ledger, fuchsia::ledger::Page* const root_page,
                  fidl::StringPtr story_name,
                  fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_info,
                  fuchsia::modular::StoryOptions story_options, ResultCall result_call)
      : LedgerOperation("SessionStorage::CreateStoryCall", ledger, root_page,
                        std::move(result_call)),
        story_name_(std::move(story_name)),
        extra_info_(std::move(extra_info)),
        story_options_(std::move(story_options)) {}

 private:
  void Run() override {
    FlowToken flow{this, &story_name_, &story_page_id_};
    ledger()->GetPage(nullptr, story_page_.NewRequest());
    story_page_->GetId([this, flow](fuchsia::ledger::PageId id) {
      story_page_id_ = std::move(id);
      Cont(flow);
    });
  }

  void Cont(FlowToken flow) {
    // TODO(security), cf. FW-174. This ID is exposed in public services
    // such as fuchsia::modular::StoryProvider.PreviousStories(),
    // fuchsia::modular::StoryController.GetInfo(),
    // fuchsia::modular::ModuleContext.GetStoryName(). We need to ensure this
    // doesn't expose internal information by being a page ID.
    // TODO(thatguy): Generate a GUID instead.
    if (!story_name_ || story_name_->empty()) {
      story_name_ = uuid::Generate();
    }

    story_data_ = fuchsia::modular::internal::StoryData::New();
    story_data_->set_story_name(story_name_.value_or(""));
    story_data_->set_story_options(std::move(story_options_));
    story_data_->set_story_page_id(std::move(story_page_id_));
    story_data_->mutable_story_info()->id = story_name_.value_or("");
    story_data_->mutable_story_info()->last_focus_time = 0;
    story_data_->mutable_story_info()->extra = std::move(extra_info_);
    operation_queue_.Add(MakeWriteStoryDataCall(page(), std::move(story_data_), [flow] {}));
  }

  fidl::StringPtr story_name_;
  fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_info_;
  fuchsia::modular::StoryOptions story_options_;

  fuchsia::ledger::PagePtr story_page_;
  fuchsia::modular::internal::StoryDataPtr story_data_;

  fuchsia::ledger::PageId story_page_id_;

  // Sub operations run in this queue.
  OperationQueue operation_queue_;
};

}  // namespace

FuturePtr<fidl::StringPtr, fuchsia::ledger::PageId> SessionStorage::CreateStory(
    fidl::StringPtr story_name, fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_info,
    fuchsia::modular::StoryOptions story_options) {
  auto ret =
      Future<fidl::StringPtr, fuchsia::ledger::PageId>::Create("SessionStorage.CreateStory.ret");
  operation_queue_.Add(std::make_unique<CreateStoryCall>(
      ledger_client_->ledger(), page(), std::move(story_name), std::move(extra_info),
      std::move(story_options), ret->Completer()));
  return ret;
}

FuturePtr<fidl::StringPtr, fuchsia::ledger::PageId> SessionStorage::CreateStory(
    fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_info,
    fuchsia::modular::StoryOptions story_options) {
  return CreateStory(nullptr /* story_name */, std::move(extra_info), std::move(story_options));
}

namespace {
class DeleteStoryCall : public Operation<> {
 public:
  DeleteStoryCall(fuchsia::ledger::Ledger* const ledger, fuchsia::ledger::Page* const session_page,
                  fidl::StringPtr story_name, ResultCall result_call)
      : Operation("SessionStorage::DeleteStoryCall", std::move(result_call)),
        ledger_(ledger),
        session_page_(session_page),
        story_name_(story_name) {}

 private:
  void Run() override {
    FlowToken flow{this};
    operation_queue_.Add(
        MakeGetStoryDataCall(session_page_, story_name_, [this, flow](auto story_data) {
          if (!story_data)
            return;
          story_data_ = std::move(*story_data);
          Cont(flow);
        }));
  }

  void Cont(FlowToken flow) {
    // Get the story page so we can remove its contents.
    ledger_->GetPage(
        std::make_unique<fuchsia::ledger::PageId>(*std::move(story_data_.mutable_story_page_id())),
        story_page_.NewRequest());
    story_page_->Clear();
    // Remove the story data in the session page.
    session_page_->Delete(to_array(StoryNameToStoryDataKey(story_data_.story_info().id)));
    // Remove the story snapshot in the session page.
    session_page_->Delete(to_array(StoryNameToStorySnapshotKey(story_data_.story_info().id)));
  }

  fuchsia::ledger::Ledger* const ledger_;      // not owned
  fuchsia::ledger::Page* const session_page_;  // not owned
  const fidl::StringPtr story_name_;

  // Intermediate state.
  OperationQueue operation_queue_;
  fuchsia::modular::internal::StoryData story_data_;
  fuchsia::ledger::PagePtr story_page_;
};
}  // namespace

FuturePtr<> SessionStorage::DeleteStory(fidl::StringPtr story_name) {
  auto ret = Future<>::Create("SessionStorage.DeleteStory.ret");
  operation_queue_.Add(std::make_unique<DeleteStoryCall>(ledger_client_->ledger(), page(),
                                                         story_name, ret->Completer()));
  return ret;
}

namespace {
class MutateStoryDataCall : public Operation<> {
 public:
  MutateStoryDataCall(fuchsia::ledger::Page* const page, fidl::StringPtr story_name,
                      fit::function<bool(fuchsia::modular::internal::StoryData* story_data)> mutate,
                      ResultCall result_call)
      : Operation("SessionStorage::MutateStoryDataCall", std::move(result_call)),
        page_(page),
        story_name_(story_name),
        mutate_(std::move(mutate)) {}

 private:
  void Run() override {
    FlowToken flow{this};

    operation_queue_.Add(MakeGetStoryDataCall(
        page_, story_name_, [this, flow](fuchsia::modular::internal::StoryDataPtr story_data) {
          if (!story_data) {
            // If the story doesn't exist, it was deleted.
            return;
          }
          if (!mutate_(story_data.get())) {
            // If no mutation happened, we're done.
            return;
          }

          operation_queue_.Add(MakeWriteStoryDataCall(page_, std::move(story_data), [flow] {}));
        }));
  }

  fuchsia::ledger::Page* const page_;  // not owned
  const fidl::StringPtr story_name_;
  fit::function<bool(fuchsia::modular::internal::StoryData* story_data)> mutate_;

  OperationQueue operation_queue_;
};

}  // namespace

FuturePtr<> SessionStorage::UpdateLastFocusedTimestamp(fidl::StringPtr story_name,
                                                       const int64_t ts) {
  auto mutate = [ts](fuchsia::modular::internal::StoryData* const story_data) {
    if (story_data->story_info().last_focus_time == ts) {
      return false;
    }
    story_data->mutable_story_info()->last_focus_time = ts;
    return true;
  };

  auto ret = Future<>::Create("SessionStorage.UpdateLastFocusedTimestamp.ret");
  operation_queue_.Add(
      std::make_unique<MutateStoryDataCall>(page(), story_name, mutate, ret->Completer()));
  return ret;
}

FuturePtr<fuchsia::modular::internal::StoryDataPtr> SessionStorage::GetStoryData(
    fidl::StringPtr story_name) {
  auto ret =
      Future<fuchsia::modular::internal::StoryDataPtr>::Create("SessionStorage.GetStoryData.ret");
  operation_queue_.Add(MakeGetStoryDataCall(page(), story_name, ret->Completer()));
  return ret;
}

// Returns a Future vector of StoryData for all stories in this session.
FuturePtr<std::vector<fuchsia::modular::internal::StoryData>> SessionStorage::GetAllStoryData() {
  auto ret = Future<std::vector<fuchsia::modular::internal::StoryData>>::Create(
      "SessionStorage.GetAllStoryData.ret");
  operation_queue_.Add(std::make_unique<ReadAllDataCall<fuchsia::modular::internal::StoryData>>(
      page(), kStoryDataKeyPrefix, XdrStoryData, ret->Completer()));
  return ret;
}

FuturePtr<> SessionStorage::UpdateStoryOptions(fidl::StringPtr story_name,
                                               fuchsia::modular::StoryOptions story_options) {
  auto ret = Future<>::Create("SessionStorage.SetOptions.ret");
  auto mutate = [story_options = std::move(story_options)](
                    fuchsia::modular::internal::StoryData* story_data) mutable {
    if (!fidl::Equals(story_data->story_options(), story_options)) {
      story_data->set_story_options(std::move(story_options));
      return true;
    }
    return false;
  };
  operation_queue_.Add(std::make_unique<MutateStoryDataCall>(page(), story_name, std::move(mutate),
                                                             ret->Completer()));
  return ret;
}

FuturePtr<std::unique_ptr<StoryStorage>> SessionStorage::GetStoryStorage(
    fidl::StringPtr story_name) {
  auto returned_future = Future<std::unique_ptr<StoryStorage>>::Create(
      "SessionStorage.GetStoryStorage.returned_future");

  operation_queue_.Add(MakeGetStoryDataCall(
      page(), story_name,
      [this, returned_future, story_name](fuchsia::modular::internal::StoryDataPtr story_data) {
        if (story_data) {
          auto story_storage =
              std::make_unique<StoryStorage>(ledger_client_, story_data->story_page_id());
          returned_future->Complete(std::move(story_storage));
        } else {
          returned_future->Complete(nullptr);
        }
      }));

  return returned_future;
}

namespace {

class WriteSnapshotCall : public Operation<> {
 public:
  WriteSnapshotCall(PageClient* page_client, fidl::StringPtr story_name,
                    fuchsia::mem::Buffer snapshot, ResultCall result_call)
      : Operation("SessionStorage::WriteSnapshotCall", std::move(result_call)),
        page_client_(page_client),
        key_(StoryNameToStorySnapshotKey(story_name)),
        snapshot_(std::move(snapshot)) {}

 private:
  void Run() override {
    FlowToken flow{this};
    page_client_->page()->CreateReferenceFromBuffer(
        std::move(snapshot_),
        [this, flow](fuchsia::ledger::Page_CreateReferenceFromBuffer_Result result) {
          if (result.is_err()) {
            FXL_LOG(ERROR) << trace_name() << " PageSnapshot.CreateReferenceFromBuffer() "
                           << zx_status_get_string(result.err());
            return;
          }
          PutReference(std::move(result.response().reference), flow);
        });
  }

  void PutReference(fuchsia::ledger::Reference reference, FlowToken flow) {
    page_client_->page()->PutReference(to_array(key_.value_or("")), std::move(reference),
                                       // TODO(MI4-1425): Experiment with declaring lazy priority.
                                       fuchsia::ledger::Priority::EAGER);
  }

  PageClient* const page_client_;
  fidl::StringPtr key_;
  fuchsia::mem::Buffer snapshot_;
};

class ReadSnapshotCall : public Operation<fuchsia::mem::BufferPtr> {
 public:
  ReadSnapshotCall(PageClient* page_client, fidl::StringPtr story_name, ResultCall result_call)
      : Operation("SessionStorage::ReadSnapshotCall", std::move(result_call)),
        page_client_(page_client),
        key_(StoryNameToStorySnapshotKey(story_name)) {}

 private:
  void Run() override {
    FlowToken flow{this, &snapshot_};

    page_snapshot_ = page_client_->NewSnapshot();
    page_snapshot_->Get(to_array(key_.value_or("")), [this,
                                         flow](fuchsia::ledger::PageSnapshot_Get_Result result) {
      if (result.is_response()) {
        snapshot_ = fidl::MakeOptional(std::move(result.response().buffer));
        return;
      }
      if (result.err() == fuchsia::ledger::Error::KEY_NOT_FOUND) {
        return;
      }
      // TODO(MI4-1425): Handle NEEDS_FETCH status if using lazy priority.
      FXL_LOG(ERROR) << trace_name() << " PageSnapshot.Get() " << fidl::ToUnderlying(result.err());
    });
  }

  // Input parameters.
  PageClient* const page_client_;
  fidl::StringPtr key_;

  // Intermediate state.
  fuchsia::ledger::PageSnapshotPtr page_snapshot_;

  // Return values.
  fuchsia::mem::BufferPtr snapshot_;
};
}  // namespace

FuturePtr<> SessionStorage::WriteSnapshot(fidl::StringPtr story_name,
                                          fuchsia::mem::Buffer snapshot) {
  auto ret = Future<>::Create("SessionStorage.WriteSnapshot.ret");
  operation_queue_.Add(
      std::make_unique<WriteSnapshotCall>(this, story_name, std::move(snapshot), ret->Completer()));
  return ret;
}

FuturePtr<fuchsia::mem::BufferPtr> SessionStorage::ReadSnapshot(fidl::StringPtr story_name) {
  auto ret = Future<fuchsia::mem::BufferPtr>::Create("SessionStorage.ReadSnapshot.ret");
  operation_queue_.Add(std::make_unique<ReadSnapshotCall>(this, story_name, ret->Completer()));
  return ret;
}

void SessionStorage::OnPageChange(const std::string& key, const std::string& value) {
  if (StartsWith(key, kStoryDataKeyPrefix)) {
    auto story_data = fuchsia::modular::internal::StoryData::New();
    if (!XdrRead(value, &story_data, XdrStoryData)) {
      FXL_LOG(ERROR) << "SessionStorage::OnPageChange : could not decode ledger "
                        "value for key "
                     << key << "\nvalue:\n"
                     << value;
      return;
    }

    auto story_name = StoryNameFromStoryDataKey(key);
    if (on_story_updated_) {
      on_story_updated_(std::move(story_name), std::move(*story_data));
    }
  } else {
    // No-op.
  }
}

void SessionStorage::OnPageDelete(const std::string& key) {
  if (on_story_deleted_) {
    // Call to StoryNameFromStoryDataKey() needed because a deleted story is
    // modelled by deleting the key, and then the value is not available.
    // TODO(thatguy,mesch): Change PageClient to supply values of deleted keys
    // and/or change modeling of deleted stories.
    on_story_deleted_(StoryNameFromStoryDataKey(key));
  }
}

}  // namespace modular
