// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "common/util/subcommand.h"

#include <iostream>
#include <string>

#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"

namespace verible {

SubcommandRegistry::SubcommandRegistry()
    : subcommand_map_{
          // Every registry comes initialized with its own generic 'help'
          // command.
          {"help",
           {[this](const SubcommandArgsRange &args, std::istream &ins,
                   std::ostream &outs,
                   std::ostream &errs) { return Help(args, ins, outs, errs); },
            "help [command]\n"
            "Prints command help.  "
            "With no command or unknown command, this lists available "
            "commands.\n"}},

          {"error",
           {[this](const SubcommandArgsRange &args, std::istream &ins,
                   std::ostream &outs, std::ostream &errs) {
              // Call with empty arguments to just get the command listing.
              const auto unused_status = Help({}, ins, outs, errs);
              return absl::InvalidArgumentError("Unknown subcommand.");
            },
            "This is not a valid command.\n", false}},
      } {
  command_listing_.emplace_back("help");
}

const SubcommandEntry &SubcommandRegistry::GetSubcommandEntry(
    absl::string_view command) const {
  const SubcommandMap &commands(subcommand_map_);
  const auto iter = commands.find(command);
  if (iter == commands.end()) {
    // Command not found, print help and exit non-zero.
    return commands.find("error")->second;
  }
  return iter->second;
}

absl::Status SubcommandRegistry::RegisterCommand(
    absl::string_view name, const SubcommandEntry &command) {
  const auto p = subcommand_map_.emplace(name, command);
  if (!p.second) {
    return absl::InvalidArgumentError(absl::StrCat(
        "A function named \"", name, "\" has already been registered."));
  }
  if (command.show_in_help) {
    command_listing_.emplace_back(name);
  }
  return absl::OkStatus();
}

absl::Status SubcommandRegistry::Help(const SubcommandArgsRange &args,
                                      std::istream &, std::ostream &,
                                      std::ostream &errs) const {
  if (args.empty()) {
    errs << "available commands:\n" << ListCommands() << std::endl;
    return absl::OkStatus();
  }

  const SubcommandEntry &entry = GetSubcommandEntry(args.front());
  errs << entry.usage << std::endl;
  return absl::OkStatus();
}

std::string SubcommandRegistry::ListCommands() const {
  return absl::StrCat("  ", absl::StrJoin(command_listing_, "\n  "), "\n");
}

}  // namespace verible
