// Copyright (c) 2012 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 "cros-disks/archive_manager.h"

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <brillo/cryptohome.h>

#include "cros-disks/platform.h"
#include "cros-disks/user.h"

namespace cros_disks {

bool ArchiveManager::ResolvePath(const std::string& path,
                                 std::string* real_path) {
  const MountNamespace mount_namespace = GetMountNamespaceFor(path);
  return platform()->GetRealPath(path, real_path);
}

bool ArchiveManager::IsInAllowedFolder(const std::string& source_path) {
  std::vector<std::string> parts;
  base::FilePath(source_path).GetComponents(&parts);

  if (parts.size() < 2 || parts[0] != "/")
    return false;

  if (parts[1] == "home")
    return parts.size() > 5 && parts[2] == "chronos" &&
           base::StartsWith(parts[3], "u-", base::CompareCase::SENSITIVE) &&
           brillo::cryptohome::home::IsSanitizedUserName(parts[3].substr(2)) &&
           parts[4] == "MyFiles";

  if (parts[1] == "media")
    return parts.size() > 4 && (parts[2] == "archive" || parts[2] == "fuse" ||
                                parts[2] == "removable");

  if (parts[1] == "run")
    return parts.size() > 8 && parts[2] == "arc" && parts[3] == "sdcard" &&
           parts[4] == "write" && parts[5] == "emulated" && parts[6] == "0";

  return false;
}

std::string ArchiveManager::SuggestMountPath(
    const std::string& source_path) const {
  // Use the archive name to name the mount directory.
  base::FilePath base_name = base::FilePath(source_path).BaseName();
  return mount_root().Append(base_name).value();
}

std::vector<gid_t> ArchiveManager::GetSupplementaryGroups() const {
  std::vector<gid_t> groups;

  // To access Play Files.
  gid_t gid;
  if (platform()->GetGroupId("android-everybody", &gid))
    groups.push_back(gid);

  return groups;
}

MountErrorType ArchiveManager::GetMountOptions(
    MountOptions* const options) const {
  DCHECK(options);

  options->SetReadOnlyOption();
  options->EnforceOption("umask=0222");
  options->EnforceOption(MountOptions::kOptionNoSymFollow);
  options->Initialize({}, true, base::NumberToString(kChronosUID),
                      base::NumberToString(kChronosAccessGID));

  return MOUNT_ERROR_NONE;
}

ArchiveManager::MountNamespace ArchiveManager::GetMountNamespaceFor(
    const std::string& path) {
  const char* const chrome_namespace = "/run/namespaces/mnt_chrome";
  // Try to enter Chrome's mount namespace.
  MountNamespace result{.guard = brillo::ScopedMountNamespace::CreateFromPath(
                            base::FilePath(chrome_namespace))};
  // Check if the given path exists in Chrome's mount namespace.
  if (result.guard && base::PathExists(base::FilePath(path))) {
    result.name = chrome_namespace;
  } else {
    // The path doesn't exist in Chrome's mount namespace. Exit the namespace.
    result.guard.reset();
  }
  return result;
}

}  // namespace cros_disks
