// 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.
#ifndef IMAGELOADER_IMAGELOADER_IMPL_H_
#define IMAGELOADER_IMAGELOADER_IMPL_H_

#include <map>
#include <string>
#include <utility>
#include <vector>

#include <base/files/file_path.h>
#include <base/gtest_prod_util.h>
#include <base/macros.h>

#include "imageloader/helper_process_proxy.h"

namespace imageloader {

using Keys = std::vector<std::vector<uint8_t>>;

struct ImageLoaderConfig {
  ImageLoaderConfig(const Keys& keys, const char* storage_path,
                    const char* mount_path)
      : keys(keys),
        storage_dir(storage_path),
        mount_path(mount_path) {}

  Keys keys;
  base::FilePath storage_dir;
  base::FilePath mount_path;
};

class ImageLoaderImpl {
 public:
  // Instantiate an object with a configuration object.
  explicit ImageLoaderImpl(ImageLoaderConfig config)
      : config_(std::move(config)) {}

  // Register a component.
  bool RegisterComponent(const std::string& name, const std::string& version,
                         const std::string& component_folder_abs_path);

  // Remove a component.
  bool RemoveComponent(const std::string& name);

  // Enumerates all mount point paths with prefix of |parent_dir| and returns
  // them with |paths|. If |dry_run| is true, no mount points are unmounted.
  // If |dry_run| is false, all mount points returned in |paths| are unmounted.
  bool CleanupAll(bool dry_run,
                  const base::FilePath& parent_dir,
                  std::vector<std::string>* paths,
                  HelperProcessProxy* proxy);

  // Cleanup a mount point at |path|.
  bool Cleanup(const base::FilePath& path, HelperProcessProxy* proxy);

  // Cleanup a Dlc mount point given Dlc |id|.
  bool UnloadDlcImage(const std::string& id, HelperProcessProxy* proxy);

  // Get component version given component name.
  std::string GetComponentVersion(const std::string& name);

  // Get component metadata given component name.
  bool GetComponentMetadata(const std::string& name,
                            std::map<std::string, std::string>* out_metadata);

  // Load the specified component. This returns the mount point or an empty
  // string on failure.
  std::string LoadComponent(const std::string& name, HelperProcessProxy* proxy);

  // Load the specified DLC image. This returns the mount point or an empty
  // string on failure.
  std::string LoadDlcImage(const std::string& id, const std::string& a_or_b,
                           HelperProcessProxy* proxy);

  // Load the specified component at a set mount point.
  bool LoadComponent(const std::string& name, const std::string& mount_point,
                     HelperProcessProxy* proxy);

  // Load the specified component from the given path.
  std::string LoadComponentAtPath(const std::string& name,
                                  const base::FilePath& absolute_path,
                                  HelperProcessProxy* proxy);

  // The directory hierarchy for a component consists of the storage_root (i.e.
  // `/var/lib/imageloader`), the component_root
  // (`/var/lib/imageloader/ComponentName`), and the version folder (i.e.
  // `/var/lib/imageloader/ComponentName/23.0.0.205`). That is:
  // [storage_root]/
  // [storage_root]/[component_root]
  // [storage_root]/[component_root]/[version]
  //
  // Inside the `component_root` there is a current version hint file:
  // [storage_root]/[component_root]/latest-version

  // Return the path to latest-version file for |component_name|.
  base::FilePath GetLatestVersionFilePath(const std::string& component_name);

  // Return the path to the [component_root] folder for |component_name|.
  base::FilePath GetComponentRoot(const std::string& component_name);

  // Return the path to a given version of |component_name|.
  base::FilePath GetVersionPath(const std::string& component_name,
                                const std::string& version);

  // Return the path to the current version of |component_name|.
  bool GetPathToCurrentComponentVersion(const std::string& component_name,
                                        base::FilePath* result);

 private:
  FRIEND_TEST_ALL_PREFIXES(ImageLoaderTest, RemoveImageAtPathRemovable);
  FRIEND_TEST_ALL_PREFIXES(ImageLoaderTest, RemoveImageAtPathNotRemovable);

  // The configuration traits.
  ImageLoaderConfig config_;

  // Remove component if removable.
  bool RemoveComponentAtPath(const std::string& name,
                             const base::FilePath& component_root,
                             const base::FilePath& component_path);

  DISALLOW_COPY_AND_ASSIGN(ImageLoaderImpl);
};

}  // namespace imageloader

#endif  // IMAGELOADER_IMAGELOADER_IMPL_H_
