// Copyright 2016 The Chromium OS 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 "imageloader_impl.h"

#include <sys/statvfs.h>
#include <sys/vfs.h>
#include </usr/include/linux/magic.h>

#include <string>

#include <base/containers/adapters.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/important_file_writer.h>
#include <base/logging.h>
#include <base/version.h>
#include <chromeos/dbus/service_constants.h>

#include "component.h"

namespace imageloader {

namespace {

using imageloader::kBadResult;

// The name of the file containing the latest component version.
constexpr char kLatestVersionFile[] = "latest-version";
// The maximum size of the latest-version file.
constexpr int kMaximumLatestVersionSize = 4096;

// |mount_base_path| is the subfolder where all components are mounted.
// For example "/mnt/imageloader."
base::FilePath GetMountPoint(const base::FilePath& mount_base_path,
                             const std::string& component_name,
                             const std::string& component_version) {
  return mount_base_path.Append(component_name).Append(component_version);
}

bool AssertComponentDirPerms(const base::FilePath& path) {
  int mode;
  if (!GetPosixFilePermissions(path, &mode)) return false;
  return mode == kComponentDirPerms;
}

}  // namespace {}

bool ImageLoaderImpl::LoadComponent(const std::string& name,
                                    const std::string& mount_point_str,
                                    HelperProcess* process) {
  base::FilePath component_path;
  if (!GetPathToCurrentComponentVersion(name, &component_path)) {
    return false;
  }

  Component component(component_path);
  if (!component.Init(config_.key)) {
    LOG(ERROR) << "Failed to initialize component: " << name;
    return false;
  }

  base::FilePath mount_point(mount_point_str);
  return component.Mount(process, mount_point);
}

std::string ImageLoaderImpl::LoadComponent(const std::string& name,
                                           HelperProcess* process) {
  base::FilePath component_path;
  if (!GetPathToCurrentComponentVersion(name, &component_path)) {
    return kBadResult;
  }

  Component component(component_path);
  if (!component.Init(config_.key)) {
    LOG(ERROR) << "Failed to initialize component: " << name;
    return kBadResult;
  }

  base::FilePath mount_point(
      GetMountPoint(config_.mount_path, name, component.manifest().version));
  return component.Mount(process, mount_point) ? mount_point.value()
                                               : kBadResult;
}

bool ImageLoaderImpl::RegisterComponent(
    const std::string& name, const std::string& version,
    const std::string& component_folder_abs_path) {
  base::FilePath components_dir(config_.storage_dir);

  // If the directory is writable by others, do not trust the components.
  if (!AssertComponentDirPerms(components_dir)) return false;

  std::string old_version_hint;
  base::FilePath version_hint_path(GetLatestVersionFilePath(name));
  bool have_old_version = base::PathExists(version_hint_path);
  if (have_old_version) {
    if (!base::ReadFileToStringWithMaxSize(version_hint_path, &old_version_hint,
                                           kMaximumLatestVersionSize)) {
      return false;
    }

    // Check for version rollback.
    base::Version current_version(old_version_hint);
    base::Version new_version(version);
    if (!new_version.IsValid()) {
      return false;
    }

    if (current_version.IsValid() && new_version <= current_version) {
      LOG(ERROR) << "Version [" << new_version << "] is not newer than ["
                 << current_version << "] for component [" << name
                 << "] and cannot be registered.";
      return false;
    }
  }

  // Check if this specific component already exists in the filesystem.
  base::FilePath component_root(GetComponentRoot(name));
  if (!base::PathExists(component_root)) {
    if (mkdir(component_root.value().c_str(), kComponentDirPerms) != 0) {
      PLOG(ERROR) << "Could not create component specific directory.";
      return false;
    }
  }

  base::FilePath component_path(component_folder_abs_path);
  Component component(component_path);
  if (!component.Init(config_.key)) return false;

  // Check that the reported version matches the component manifest version.
  if (component.manifest().version != version) {
    LOG(ERROR) << "Version in signed manifest does not match the reported "
                  "component version.";
    return false;
  }

  // Take ownership of the component and verify it.
  base::FilePath version_path(GetVersionPath(name, version));
  // If |version_path| exists but was not the active version, ImageLoader
  // probably crashed previously and could not cleanup.
  if (base::PathExists(version_path)) {
    base::DeleteFile(version_path, /*recursive=*/true);
  }

  if (mkdir(version_path.value().c_str(), kComponentDirPerms) != 0) {
    PLOG(ERROR) << "Could not create directory for new component version.";
    return false;
  }

  if (!component.CopyTo(version_path)) {
    base::DeleteFile(version_path, /*recursive=*/true);
    return false;
  }

  if (!base::ImportantFileWriter::WriteFileAtomically(version_hint_path,
                                                      version)) {
    base::DeleteFile(version_path, /*recursive=*/true);
    LOG(ERROR) << "Failed to update current version hint file.";
    return false;
  }

  // Now delete the old component version, if there was one.
  if (have_old_version) {
    base::DeleteFile(GetVersionPath(name, old_version_hint),
                     /*recursive=*/true);
  }

  return true;
}

std::string ImageLoaderImpl::GetComponentVersion(const std::string& name) {
  base::FilePath component_path;
  if (!GetPathToCurrentComponentVersion(name, &component_path)) {
    return kBadResult;
  }

  Component component(component_path);
  if (!component.Init(config_.key)) return kBadResult;

  return component.manifest().version;
}

base::FilePath ImageLoaderImpl::GetLatestVersionFilePath(
    const std::string& component_name) {
  return config_.storage_dir.Append(component_name).Append(kLatestVersionFile);
}

base::FilePath ImageLoaderImpl::GetVersionPath(
    const std::string& component_name, const std::string& version) {
  return config_.storage_dir.Append(component_name).Append(version);
}

base::FilePath ImageLoaderImpl::GetComponentRoot(
    const std::string& component_name) {
  return config_.storage_dir.Append(component_name);
}

bool ImageLoaderImpl::GetPathToCurrentComponentVersion(
    const std::string& component_name, base::FilePath* result) {
  base::FilePath component_root(GetComponentRoot(component_name));
  // Read the latest version file.
  std::string latest_version;
  if (!base::ReadFileToStringWithMaxSize(
          GetLatestVersionFilePath(component_name), &latest_version,
          kMaximumLatestVersionSize)) {
    LOG(ERROR) << "Failed to read latest-version file.";
    return false;
  }

  *result = component_root.Append(latest_version);
  return true;
}

}  // namespace imageloader
