// Copyright 2020 The Cobalt 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.

#include "starboard/loader_app/drain_file.h"

#include <algorithm>
#include <string>
#include <vector>

#include "starboard/common/file.h"
#include "starboard/common/log.h"
#include "starboard/configuration_constants.h"
#include "starboard/directory.h"
#include "starboard/string.h"

#ifdef __cplusplus
extern "C" {
#endif

const SbTime kDrainFileAgeUnit = kSbTimeSecond;
const SbTime kDrainFileMaximumAge = kSbTimeHour;
const char kDrainFilePrefix[] = "d_";

#ifdef __cplusplus
}  // extern "C"
#endif

namespace starboard {
namespace loader_app {
namespace {

std::string ExtractAppKey(const std::string& str) {
  const size_t begin = str.find_first_of('_') + 1;
  const size_t end = str.find_last_of('_');

  if ((begin == std::string::npos) || (end == std::string::npos) ||
      (end - begin < 1))
    return "";

  return str.substr(begin, end - begin);
}

SbTime ExtractTimestamp(const std::string& str) {
  const size_t index = str.find_last_of('_') + 1;

  if ((index == std::string::npos) || (index == str.size() - 1))
    return 0;

  const std::string timestamp = str.substr(index, str.size() - index);

  return SbTime(SbStringParseUInt64(timestamp.c_str(), NULL, 10)) *
         kDrainFileAgeUnit;
}

bool IsExpired(const std::string& filename) {
  const SbTime timestamp = ExtractTimestamp(filename);
  return timestamp + kDrainFileMaximumAge < SbTimeGetNow();
}

std::vector<std::string> FindAllWithPrefix(const std::string& dir,
                                           const std::string& prefix) {
  SbDirectory slot = SbDirectoryOpen(dir.c_str(), NULL);

  if (!SbDirectoryIsValid(slot)) {
    SB_LOG(ERROR) << "Failed to open provided directory '" << dir << "'";
    return std::vector<std::string>();
  }

  std::vector<std::string> filenames;

#if SB_API_VERSION >= 12
  std::vector<char> filename(kSbFileMaxName);

  while (SbDirectoryGetNext(slot, filename.data(), filename.size())) {
    if (!SbStringCompareAll(filename.data(), ".") ||
        !SbStringCompareAll(filename.data(), ".."))
      continue;
    if (!SbStringCompare(prefix.data(), filename.data(), prefix.size()))
      filenames.push_back(std::string(filename.data()));
  }
#else
  SbDirectoryEntry entry;

  while (SbDirectoryGetNext(slot, &entry)) {
    if (!SbStringCompareAll(entry.name, ".") ||
        !SbStringCompareAll(entry.name, ".."))
      continue;
    if (!SbStringCompare(prefix.data(), entry.name, prefix.size()))
      filenames.push_back(std::string(entry.name));
  }
#endif

  SbDirectoryClose(slot);
  return filenames;
}

void Rank(const char* dir, char* app_key, size_t len) {
  SB_DCHECK(dir);
  SB_DCHECK(app_key);

  std::vector<std::string> filenames = FindAllWithPrefix(dir, kDrainFilePrefix);

  std::remove_if(filenames.begin(), filenames.end(), IsExpired);

  if (filenames.empty())
    return;

  // This lambda compares two strings, each string being a drain file name. This
  // function returns |true| when |left| has an earlier timestamp than |right|,
  // or when |left| is ASCII-betically lower than |right| if their timestamps
  // are equal.
  auto compare_filenames = [](const std::string& left,
                              const std::string& right) -> bool {
    const SbTime left_timestamp = ExtractTimestamp(left);
    const SbTime right_timestamp = ExtractTimestamp(right);

    if (left_timestamp != right_timestamp)
      return left_timestamp < right_timestamp;

    const std::string left_app_key = ExtractAppKey(left);
    const std::string right_app_key = ExtractAppKey(right);

    return SbStringCompare(left_app_key.c_str(), right_app_key.c_str(),
                           right_app_key.size()) < 0;
  };

  std::sort(filenames.begin(), filenames.end(), compare_filenames);

  const std::string& ranking_app_key = ExtractAppKey(filenames.front());

  if (SbStringCopy(app_key, ranking_app_key.c_str(), len) >= len)
    SB_LOG(ERROR) << "Returned value was truncated";
}

}  // namespace

namespace drain_file {

bool TryDrain(const char* dir, const char* app_key) {
  SB_DCHECK(dir);
  SB_DCHECK(app_key);

  std::vector<std::string> filenames = FindAllWithPrefix(dir, kDrainFilePrefix);

  for (const auto& filename : filenames) {
    if (IsExpired(filename))
      continue;
    if (filename.find(app_key) == std::string::npos)
      return false;
    SB_LOG(INFO) << "Found valid drain file '" << filename << "'";
    return true;
  }

  std::string filename(kDrainFilePrefix);
  filename.append(app_key);
  filename.append("_");
  filename.append(std::to_string(SbTimeGetNow() / kDrainFileAgeUnit));

  SB_DCHECK(filename.size() <= kSbFileMaxName);

  std::string path(dir);
  path.append(kSbFileSepString);
  path.append(filename);

  SbFileError error = kSbFileOk;
  SbFile file = SbFileOpen(path.c_str(), kSbFileCreateAlways | kSbFileWrite,
                           NULL, &error);

  SB_DCHECK(error == kSbFileOk);
  SB_DCHECK(SbFileClose(file));

  SB_LOG(INFO) << "Created drain file at '" << path << "'";

  return true;
}

bool RankAndCheck(const char* dir, const char* app_key) {
  SB_DCHECK(dir);
  SB_DCHECK(app_key);

  std::vector<char> ranking_app_key(kSbFileMaxName);

  Rank(dir, ranking_app_key.data(), ranking_app_key.size());

  return !SbStringCompareAll(ranking_app_key.data(), app_key);
}

bool Remove(const char* dir, const char* app_key) {
  SB_DCHECK(dir);
  SB_DCHECK(app_key);

  const std::string prefix = std::string(kDrainFilePrefix) + app_key;
  const std::vector<std::string> filenames =
      FindAllWithPrefix(dir, prefix.c_str());

  for (const auto& filename : filenames) {
    const std::string path = dir + std::string(kSbFileSepString) + filename;

    if (!SbFileDelete(path.c_str()))
      return false;
  }
  return true;
}

void Clear(const char* dir, const char* app_key, bool expired) {
  SB_DCHECK(dir);

  std::vector<std::string> filenames = FindAllWithPrefix(dir, kDrainFilePrefix);

  for (const auto& filename : filenames) {
    if (expired && !IsExpired(filename))
      continue;
    if (app_key && (filename.find(app_key) != std::string::npos))
      continue;

    const std::string path = dir + std::string(kSbFileSepString) + filename;

    if (!SbFileDelete(path.c_str()))
      SB_LOG(ERROR) << "Failed to remove expired drain file at '" << filename
                    << "'";
  }
}

void PrepareDirectory(const char* dir, const char* app_key) {
  SB_DCHECK(dir);
  SB_DCHECK(app_key);

  const std::string prefix = std::string(kDrainFilePrefix) + app_key;
  const std::vector<std::string> entries = FindAllWithPrefix(dir, "");

  for (const auto& entry : entries) {
    if (!SbStringCompare(entry.c_str(), prefix.c_str(), prefix.size()))
      continue;

    std::string path(dir);
    path.append(kSbFileSepString);
    path.append(entry);

    SbFileDeleteRecursive(path.c_str(), false);
  }
}

bool Draining(const char* dir, const char* app_key) {
  SB_DCHECK(dir);

  std::string prefix(kDrainFilePrefix);

  if (app_key)
    prefix.append(app_key);

  const std::vector<std::string> filenames =
      FindAllWithPrefix(dir, prefix.c_str());

  for (const auto& filename : filenames) {
    if (!IsExpired(filename))
      return true;
  }
  return false;
}

}  // namespace drain_file
}  // namespace loader_app
}  // namespace starboard

#ifdef __cplusplus
extern "C" {
#endif

bool DrainFileTryDrain(const char* dir, const char* app_key) {
  return starboard::loader_app::drain_file::TryDrain(dir, app_key);
}

bool DrainFileRankAndCheck(const char* dir, const char* app_key) {
  return starboard::loader_app::drain_file::RankAndCheck(dir, app_key);
}

bool DrainFileRemove(const char* dir, const char* app_key) {
  return starboard::loader_app::drain_file::Remove(dir, app_key);
}

void DrainFileClear(const char* dir, const char* app_key, bool expired) {
  starboard::loader_app::drain_file::Clear(dir, app_key, expired);
}

void DrainFilePrepareDirectory(const char* dir, const char* app_key) {
  starboard::loader_app::drain_file::PrepareDirectory(dir, app_key);
}

bool DrainFileDraining(const char* dir, const char* app_key) {
  return starboard::loader_app::drain_file::Draining(dir, app_key);
}

#ifdef __cplusplus
}  // extern "C"
#endif
