// 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/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[arraysize(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 Master 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;
}
