// 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/slot_management.h"

#include <vector>

#include "starboard/common/log.h"
#include "starboard/common/string.h"
#include "starboard/configuration_constants.h"
#include "starboard/elf_loader/elf_loader_constants.h"
#include "starboard/elf_loader/sabi_string.h"
#include "starboard/event.h"
#include "starboard/file.h"
#include "starboard/loader_app/app_key_files.h"
#include "starboard/loader_app/drain_file.h"
#include "starboard/loader_app/installation_manager.h"
#include "starboard/memory.h"
#include "starboard/string.h"
#include "third_party/crashpad/wrapper/wrapper.h"

namespace starboard {
namespace loader_app {
namespace {

// The max number of installations slots.
const int kMaxNumInstallations = 3;

// Relative path for the Cobalt so file.
const char kCobaltLibraryPath[] = "lib";

// Filename for the Cobalt binary.
const char kCobaltLibraryName[] = "libcobalt.so";

// Filename for the compressed Cobalt binary.
const char kCompressedCobaltLibraryName[] = "libcobalt.lz4";

// Relative path for the content directory of
// the Cobalt installation.
const char kCobaltContentPath[] = "content";

}  // namespace

int RevertBack(int current_installation,
               const std::string& app_key,
               bool mark_bad) {
  SB_LOG(INFO) << "RevertBack current_installation=" << current_installation;
  SB_DCHECK(current_installation != 0);
  if (mark_bad) {
    std::vector<char> installation_path(kSbFileMaxPath);
    if (ImGetInstallationPath(current_installation, installation_path.data(),
                              kSbFileMaxPath) != IM_ERROR) {
      std::string bad_app_key_file_path =
          starboard::loader_app::GetBadAppKeyFilePath(installation_path.data(),
                                                      app_key);
      if (bad_app_key_file_path.empty()) {
        SB_LOG(WARNING) << "Failed to get bad app key file path for path="
                        << installation_path.data()
                        << " and app_key=" << app_key;
      } else {
        if (!starboard::loader_app::CreateAppKeyFile(bad_app_key_file_path)) {
          SB_LOG(WARNING) << "Failed to create bad app key file: "
                          << bad_app_key_file_path;
        }
      }
    } else {
      SB_LOG(WARNING) << "Failed to get installation path for index: "
                      << current_installation;
    }
  }
  current_installation = ImRevertToSuccessfulInstallation();
  return current_installation;
}

bool CheckBadFileExists(const char* installation_path, const char* app_key) {
  std::string bad_app_key_file_path =
      starboard::loader_app::GetBadAppKeyFilePath(installation_path, app_key);
  SB_DCHECK(!bad_app_key_file_path.empty());
  SB_LOG(INFO) << "bad_app_key_file_path: " << bad_app_key_file_path;
  SB_LOG(INFO) << "bad_app_key_file_path SbFileExists: "
               << SbFileExists(bad_app_key_file_path.c_str());
  return !bad_app_key_file_path.empty() &&
         SbFileExists(bad_app_key_file_path.c_str());
}

bool AdoptInstallation(int current_installation,
                       const char* installation_path,
                       const char* app_key) {
  SB_LOG(INFO) << "AdoptInstallation: current_installation="
               << current_installation
               << " installation_path=" << installation_path
               << " app_key=" << app_key;
  // Check that a good file exists from at least one app before adopting.
  if (!AnyGoodAppKeyFile(installation_path)) {
    SB_LOG(ERROR) << "No good files present";
    return false;
  }
  std::string good_app_key_file_path =
      starboard::loader_app::GetGoodAppKeyFilePath(installation_path, app_key);
  if (good_app_key_file_path.empty()) {
    SB_LOG(WARNING) << "Failed to get good app key file path for app_key="
                    << app_key;
    return false;
  }

  if (!SbFileExists(good_app_key_file_path.c_str())) {
    if (!starboard::loader_app::CreateAppKeyFile(good_app_key_file_path)) {
      SB_LOG(WARNING) << "Failed to create good app key file";
      return false;
    }
    if (ImResetInstallation(current_installation) == IM_ERROR) {
      return false;
    }
    if (ImRollForward(current_installation) == IM_ERROR) {
      SB_LOG(WARNING) << "Failed to roll forward";
      return false;
    }
  }
  return true;
}

void* LoadSlotManagedLibrary(const std::string& app_key,
                             const std::string& alternative_content_path,
                             LibraryLoader* library_loader,
                             bool use_compression,
                             bool use_memory_mapped_file) {
  if (use_compression && use_memory_mapped_file) {
    SB_LOG(ERROR) << "Using both compression and mmap files is not supported";
    return NULL;
  }
  // Initialize the Installation Manager.
  SB_CHECK(ImInitialize(kMaxNumInstallations, app_key.c_str()) == IM_SUCCESS)
      << "Abort. Failed to initialize Installation Manager";

  // Roll forward if needed.
  if (ImRollForwardIfNeeded() == IM_ERROR) {
    SB_LOG(WARNING) << "Failed to roll forward";
  }

  // TODO: Try to simplify the loop.
  // Loop by priority.
  int current_installation = ImGetCurrentInstallationIndex();
  while (current_installation != IM_ERROR) {
    // if not successful and num_tries_left > 0 decrement and try to
    // load the library.
    if (ImGetInstallationStatus(current_installation) !=
        IM_INSTALLATION_STATUS_SUCCESS) {
      int num_tries_left = ImGetInstallationNumTriesLeft(current_installation);
      if (num_tries_left == IM_ERROR || num_tries_left <= 0 ||
          ImDecrementInstallationNumTries(current_installation) == IM_ERROR) {
        SB_LOG(INFO) << "Out of retries";
        // If no more tries are left or if we have hard failure,
        // discard the image and auto rollback, but only if
        // the current image is not the system image.
        if (current_installation != 0) {
          current_installation =
              RevertBack(current_installation, app_key, true /* mark_bad */);
        }
      }
    }

    SB_LOG(INFO) << "Try to load the Cobalt binary";
    SB_LOG(INFO) << "current_installation=" << current_installation;

    //  Try to load the image. Failures here discard the image.
    std::vector<char> installation_path(kSbFileMaxPath);
    if (ImGetInstallationPath(current_installation, installation_path.data(),
                              kSbFileMaxPath) == IM_ERROR) {
      SB_LOG(ERROR) << "Failed to find library file";

      // Hard failure. Discard the image and auto rollback, but only if
      // the current image is not the system image.
      if (current_installation != 0) {
        current_installation =
            RevertBack(current_installation, app_key, true /* mark_bad */);
        continue;
      } else {
        // The system image at index 0 failed.
        return NULL;
      }
    }

    SB_DLOG(INFO) << "installation_path=" << installation_path.data();

    if (current_installation != 0) {
      // Cleanup all expired files from all apps.
      DrainFileClearExpired(installation_path.data());

      // Cleanup all drain files from the current app.
      DrainFileClearForApp(installation_path.data(), app_key.c_str());

      // Check for bad file.
      if (CheckBadFileExists(installation_path.data(), app_key.c_str())) {
        SB_LOG(INFO) << "Bad app key file";
        current_installation =
            RevertBack(current_installation, app_key, true /* mark_bad */);
        continue;
      }
      // If the current installation is in use by an updater roll back.
      if (DrainFileIsAnotherAppDraining(installation_path.data(),
                                        app_key.c_str())) {
        SB_LOG(INFO) << "Active slot draining";
        current_installation =
            RevertBack(current_installation, app_key, false /* mark_bad */);
        continue;
      }
      // Adopt installation performed from different app.
      if (!AdoptInstallation(current_installation, installation_path.data(),
                             app_key.c_str())) {
        SB_LOG(INFO) << "Unable to adopt installation";
        current_installation =
            RevertBack(current_installation, app_key, true /* mark_bad */);
        continue;
      }
    }

    // installation_n/lib/libcobalt.so
    std::vector<char> lib_path(kSbFileMaxPath);
    std::string library_name;
    if (use_compression) {
      library_name = kCompressedCobaltLibraryName;
    } else {
      library_name = kCobaltLibraryName;
    }
    SbStringFormatF(lib_path.data(), kSbFileMaxPath, "%s%s%s%s%s",
                    installation_path.data(), kSbFileSepString,
                    kCobaltLibraryPath, kSbFileSepString, library_name.c_str());

    SB_LOG(INFO) << "lib_path=" << lib_path.data();

    std::string content;
    if (alternative_content_path.empty()) {
      // installation_n/content
      std::vector<char> content_path(kSbFileMaxPath);
      SbStringFormatF(content_path.data(), kSbFileMaxPath, "%s%s%s",
                      installation_path.data(), kSbFileSepString,
                      kCobaltContentPath);
      content = content_path.data();
    } else {
      content = alternative_content_path.c_str();
    }

    SB_LOG(INFO) << "content=" << content;

    if (!library_loader->Load(lib_path.data(), content.c_str(), use_compression,
                              use_memory_mapped_file)) {
      SB_LOG(WARNING) << "Failed to load Cobalt!";

      // Hard failure. Discard the image and auto rollback, but only if
      // the current image is not the system image.
      if (current_installation != 0) {
        current_installation =
            RevertBack(current_installation, app_key, true /* mark_bad */);
        continue;
      } else {
        // The system image at index 0 failed.
        return NULL;
      }
    }

    EvergreenInfo evergreen_info;
    GetEvergreenInfo(&evergreen_info);
    if (!third_party::crashpad::wrapper::AddEvergreenInfoToCrashpad(
            evergreen_info)) {
      SB_LOG(ERROR)
          << "Could not send Cobalt library information into Crashapd.";
    } else {
      SB_LOG(INFO) << "Loaded Cobalt library information into Crashpad.";
    }

    auto get_evergreen_sabi_string_func = reinterpret_cast<const char* (*)()>(
        library_loader->Resolve("GetEvergreenSabiString"));

    if (!CheckSabi(get_evergreen_sabi_string_func)) {
      SB_LOG(ERROR) << "CheckSabi failed";
      // Hard failure. Discard the image and auto rollback, but only if
      // the current image is not the system image.
      if (current_installation != 0) {
        current_installation =
            RevertBack(current_installation, app_key, true /* mark_bad */);
        continue;
      } else {
        // The system image at index 0 failed.
        return NULL;
      }
    }

    auto get_user_agent_func = reinterpret_cast<const char* (*)()>(
        library_loader->Resolve("GetCobaltUserAgentString"));
    if (!get_user_agent_func) {
      SB_LOG(ERROR) << "Failed to get user agent string";
    } else {
      CrashpadAnnotations cobalt_version_info;
      memset(&cobalt_version_info, 0, sizeof(CrashpadAnnotations));
      starboard::strlcpy(cobalt_version_info.user_agent_string,
                         get_user_agent_func(), USER_AGENT_STRING_MAX_SIZE);
      third_party::crashpad::wrapper::AddAnnotationsToCrashpad(
          cobalt_version_info);
      SB_DLOG(INFO) << "Added user agent string to Crashpad.";
    }

    SB_DLOG(INFO) << "Successfully loaded Cobalt!\n";
    void* p = library_loader->Resolve("SbEventHandle");
    if (p != NULL) {
      SB_DLOG(INFO) << "Symbol Lookup succeeded address: " << p;
      return p;
    } else {
      SB_LOG(ERROR) << "Symbol Lookup failed\n";

      // Hard failure. Discard the image and auto rollback, but only if
      // the current image is not the system image.
      if (current_installation != 0) {
        current_installation =
            RevertBack(current_installation, app_key, true /* mark_bad */);
        continue;
      } else {
        // The system image at index 0 failed.
        return NULL;
      }
    }
  }
  return NULL;
}

}  // namespace loader_app
}  // namespace starboard
