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

// Command line utility to mount and unmount ChromeOS ConfigFS.

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <base/macros.h>
#include <base/stl_util.h>
#include <base/strings/string_util.h>
#include <brillo/syslog_logging.h>

#include "chromeos-config/libcros_config/cros_config.h"

static int Mount(const std::string& progname,
                 const std::vector<std::string>& args) {
  brillo::CrosConfig cros_config;
  base::FilePath source(args[0]);
  base::FilePath target(args[1]);
  if (!cros_config.MountConfigFS(source, target)) {
    std::cerr << "Mount failed!" << std::endl;
    return 1;
  }
  return 0;
}

static int MountFallback(const std::string& progname,
                         const std::vector<std::string>& args) {
  brillo::CrosConfig cros_config;
  base::FilePath target(args[0]);
  if (!cros_config.MountFallbackConfigFS(target)) {
    std::cerr << "Fallback mount failed!" << std::endl;
    return 1;
  }
  return 0;
}

static int Unmount(const std::string& progname,
                   const std::vector<std::string>& args) {
  brillo::CrosConfig cros_config;
  base::FilePath target(args[0]);
  if (!cros_config.Unmount(target)) {
    std::cerr << "Unmount failed!" << std::endl;
    return 1;
  }
  return 0;
}

static int PrintUsage(const std::string& progname,
                      const std::vector<std::string>& args);

static struct {
  std::vector<std::string> names;
  std::vector<std::string> argnames;
  std::string description;
  int (*handler)(const std::string& progname,
                 const std::vector<std::string>& args);
} subcommands[] = {
    {
        .names = {"mount"},
        .argnames = {"source", "target"},
        .description = "Mount a ChromeOS ConfigFS image for unibuild.",
        .handler = Mount,
    },
    {
        .names = {"mount-fallback"},
        .argnames = {"target"},
        .description =
            "Mount a ChromeOS ConfigFS fallback system for non-unibuild.",
        .handler = MountFallback,
    },
    {
        .names = {"unmount"},
        .argnames = {"target"},
        .description = "Unmount a previously mounted ChromeOS ConfigFS.",
        .handler = Unmount,
    },
    {
        .names = {"help", "--help", "-h"},
        .argnames = {},
        .description = "Print usage.",
        .handler = PrintUsage,
    },
};

static int PrintUsage(const std::string& progname,
                      const std::vector<std::string>& args) {
  struct {
    std::string usage;
    std::string description;
  } usagestrings[base::size(subcommands)];

  size_t max_usage_len = 0;
  auto usagestrings_it = usagestrings;
  for (auto& subcommand : subcommands) {
    auto& usagestring = *usagestrings_it++;
    usagestring.usage = "  " + progname + " ";
    if (subcommand.names.size() == 1) {
      usagestring.usage += subcommand.names[0];
    } else {
      usagestring.usage += "{" + base::JoinString(subcommand.names, "|") + "}";
    }
    for (auto& argname : subcommand.argnames) {
      usagestring.usage += " <" + argname + ">";
    }
    max_usage_len = std::max(usagestring.usage.size(), max_usage_len);
    usagestring.description = subcommand.description;
  }

  std::cerr << "ChromeOS Model Configuration: Filesytem Manager" << std::endl
            << std::endl
            << "Usage:" << std::endl;
  for (auto& usagestring : usagestrings) {
    std::cerr << std::left << std::setw(max_usage_len) << usagestring.usage
              << "  " << usagestring.description << std::endl;
  }
  return 0;
}

int main(const int argc, const char* const argv[]) {
  std::string progname(argv[0]);
  if (argc < 2) {
    PrintUsage(progname, {});
    return 1;
  }

  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderrIfTty);

  std::string subcmd_name(argv[1]);
  std::vector<std::string> args(argv + 2, argv + argc);
  for (auto& subcommand : subcommands) {
    if (std::any_of(subcommand.names.begin(), subcommand.names.end(),
                    [&subcmd_name](const std::string& name) {
                      return name == subcmd_name;
                    })) {
      if (args.size() != subcommand.argnames.size()) {
        PrintUsage(progname, {});
        std::cerr << std::endl
                  << subcmd_name << " takes " << subcommand.argnames.size()
                  << " arguments, " << args.size() << " given." << std::endl;
        return 1;
      }
      return subcommand.handler(progname, args);
    }
  }

  PrintUsage(progname, {});
  std::cerr << std::endl
            << "Unrecognized subcommand: " << subcmd_name << std::endl;
  return 1;
}
