/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * 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 <iostream>
#include <ostream>
#include <string>
#include <unordered_map>
#include <vector>

#include <android-base/logging.h>
#include <android-base/strings.h>
#include <gflags/gflags.h>

#include "common/libs/utils/subprocess.h"
#include "host/commands/assemble_cvd/display_flags.h"
#include "host/commands/assemble_cvd/flags_defaults.h"
#include "host/libs/config/cuttlefish_config.h"

DEFINE_uint32(instance_num, 1, "Which instance to read the configs from");
DEFINE_uint32(width, 0,
              "When adding a display, the width of the display in pixels");
DEFINE_uint32(height, 0,
              "When adding a display, the height of the display in pixels");
DEFINE_uint32(dpi, 0,
              "When adding a display, the pixels per inch of the display");
DEFINE_uint32(refresh_rate_hz, 0,
              "When adding a display, the refresh rate of the display in "
              "Hertz");

DEFINE_string(display0, "", cuttlefish::kDisplayHelp);
DEFINE_string(display1, "", cuttlefish::kDisplayHelp);
DEFINE_string(display2, "", cuttlefish::kDisplayHelp);
DEFINE_string(display3, "", cuttlefish::kDisplayHelp);

namespace cuttlefish {
namespace {

static const std::string kUsage =
    R"(Cuttlefish Virtual Device (CVD) Display CLI.

usage: cvd display <command> <args>

Commands:
    help                Print this message.
    help <command>      Print help for a command.
    add                 Adds a new display to a given device.
    list                Prints the currently connected displays.
    remove              Removes a display from a given device.
)";

static const std::string kAddUsage =
    R"(Cuttlefish Virtual Device (CVD) Display CLI.

Adds and connects a display to the given virtual device.

usage: cvd display add --width=720 --height=1280

       cvd display add \\
        --display0=width=1280,height=800
        --display1=width=1920,height=1080,refresh_rate_hz=60
)";

static const std::string kListUsage =
    R"(Cuttlefish Virtual Device (CVD) Display CLI.

Lists all of the displays currently connected to a given virtual device.

usage: cvd display list
)";

static const std::string kRemoveUsage =
    R"(Cuttlefish Virtual Device (CVD) Display CLI.

Disconnects and removes a display from the given virtual device.

usage: cvd display remove <display index>
       cvd display remove <display index> <display index> ...
)";

static const std::unordered_map<std::string, std::string> kSubCommandUsages = {
    {"add", kAddUsage},
    {"list", kListUsage},
    {"help", kUsage},
    {"remove", kRemoveUsage},
};

Result<int> RunCrosvmDisplayCommand(const std::vector<std::string>& args) {
  auto config = cuttlefish::CuttlefishConfig::Get();
  if (!config) {
    return CF_ERR("Failed to get Cuttlefish config.");
  }
  // TODO(b/260649774): Consistent executable API for selecting an instance
  auto instance = config->ForInstance(FLAGS_instance_num);

  const std::string crosvm_binary_path = instance.crosvm_binary();
  const std::string crosvm_control_path =
      instance.PerInstanceInternalUdsPath("crosvm_control.sock");

  cuttlefish::Command command(crosvm_binary_path);
  command.AddParameter("gpu");
  for (const std::string& arg : args) {
    command.AddParameter(arg);
  }
  command.AddParameter(crosvm_control_path);

  std::string out;
  std::string err;
  auto ret = RunWithManagedStdio(std::move(command), NULL, &out, &err);
  if (ret != 0) {
    std::cerr << "Failed to run crosvm display command: ret code: " << ret
              << "\n"
              << out << "\n"
              << err;
    return ret;
  }

  std::cerr << err << std::endl;
  std::cout << out << std::endl;
  return 0;
}

Result<int> DoHelp(const std::vector<std::string>& args) {
  if (args.empty()) {
    std::cout << kUsage << std::endl;
    return 0;
  }

  const std::string& subcommand_str = args[0];
  auto subcommand_usage = kSubCommandUsages.find(subcommand_str);
  if (subcommand_usage == kSubCommandUsages.end()) {
    std::cerr << "Unknown subcommand '" << subcommand_str
              << "'. See `cvd display help`" << std::endl;
    return 1;
  }

  std::cout << subcommand_usage->second << std::endl;
  return 0;
}

Result<std::optional<CuttlefishConfig::DisplayConfig>>
ParseLegacyDisplayFlags() {
  if (FLAGS_width == 0 && FLAGS_height == 0 && FLAGS_dpi == 0 &&
      FLAGS_refresh_rate_hz == 0) {
    return std::nullopt;
  }

  CF_EXPECT_GT(FLAGS_width, 0,
               "Must specify valid --width flag. Usage:\n"
                   << kAddUsage);
  CF_EXPECT_GT(FLAGS_height, 0,
               "Must specify valid --height flag. Usage:\n"
                   << kAddUsage);
  CF_EXPECT_GT(FLAGS_dpi, 0,
               "Must specify valid --dpi flag. Usage:\n"
                   << kAddUsage);
  CF_EXPECT_GT(FLAGS_refresh_rate_hz, 0,
               "Must specify valid --refresh_rate_hz flag. Usage:\n"
                   << kAddUsage);

  const int display_width = FLAGS_width;
  const int display_height = FLAGS_height;
  const int display_dpi = FLAGS_dpi > 0 ? FLAGS_dpi : CF_DEFAULTS_DISPLAY_DPI;
  const int display_rr = FLAGS_refresh_rate_hz > 0
                             ? FLAGS_refresh_rate_hz
                             : CF_DEFAULTS_DISPLAY_REFRESH_RATE;

  return CuttlefishConfig::DisplayConfig{
      .width = display_width,
      .height = display_height,
      .dpi = display_dpi,
      .refresh_rate_hz = display_rr,
  };
}

Result<int> DoAdd(const std::vector<std::string>&) {
  std::vector<CuttlefishConfig::DisplayConfig> display_configs;

  auto display = CF_EXPECT(ParseLegacyDisplayFlags());
  if (display) {
    display_configs.push_back(*display);
  }
  auto display0 = CF_EXPECT(ParseDisplayConfig(FLAGS_display0));
  if (display0) {
    display_configs.push_back(*display0);
  }
  auto display1 = CF_EXPECT(ParseDisplayConfig(FLAGS_display1));
  if (display1) {
    display_configs.push_back(*display1);
  }
  auto display2 = CF_EXPECT(ParseDisplayConfig(FLAGS_display2));
  if (display2) {
    display_configs.push_back(*display2);
  }
  auto display3 = CF_EXPECT(ParseDisplayConfig(FLAGS_display3));
  if (display3) {
    display_configs.push_back(*display3);
  }

  if (display_configs.empty()) {
    return CF_ERR("No displays params provided. Usage:\n" << kAddUsage);
  }

  std::vector<std::string> add_displays_command_args;
  add_displays_command_args.push_back("add-displays");

  for (const auto& display_config : display_configs) {
    const std::string w = std::to_string(display_config.width);
    const std::string h = std::to_string(display_config.height);
    const std::string dpi = std::to_string(display_config.dpi);
    const std::string rr = std::to_string(display_config.refresh_rate_hz);

    const std::string add_display_flag =
        "--gpu-display=" + android::base::Join(
                               std::vector<std::string>{
                                   "mode=windowed[" + w + "," + h + "]",
                                   "dpi=[" + dpi + "," + dpi + "]",
                                   "refresh-rate=" + rr,
                               },
                               ",");

    add_displays_command_args.push_back(add_display_flag);
  }

  return CF_EXPECT(RunCrosvmDisplayCommand(add_displays_command_args));
}

Result<int> DoList(const std::vector<std::string>&) {
  return CF_EXPECT(RunCrosvmDisplayCommand({"list-displays"}));
}

Result<int> DoRemove(const std::vector<std::string>& args) {
  if (args.empty()) {
    std::cerr << "Must specify the display id to remove. Usage:" << std::endl;
    std::cerr << kRemoveUsage << std::endl;
    return 1;
  }

  std::vector<std::string> remove_displays_command_args;
  remove_displays_command_args.push_back("remove-displays");
  for (const auto& arg : args) {
    remove_displays_command_args.push_back("--display-id=" + arg);
  }

  return CF_EXPECT(RunCrosvmDisplayCommand(remove_displays_command_args));
}

using DisplaySubCommand = Result<int> (*)(const std::vector<std::string>&);

int DisplayMain(int argc, char** argv) {
  ::android::base::InitLogging(argv, android::base::StderrLogger);
  ::gflags::SetUsageMessage(kUsage);
  ::gflags::ParseCommandLineFlags(&argc, &argv, true);

  std::vector<std::string> args;
  for (int i = 1; i < argc; i++) {
    args.push_back(argv[i]);
  }

  if (args.empty()) {
    args.push_back("help");
  }

  const std::unordered_map<std::string, DisplaySubCommand> kSubCommands = {
      {"add", DoAdd},
      {"list", DoList},
      {"help", DoHelp},
      {"remove", DoRemove},
  };

  const auto command_str = args[0];
  args.erase(args.begin());

  auto command_func_it = kSubCommands.find(command_str);
  if (command_func_it == kSubCommands.end()) {
    std::cerr << "Unknown display command: '" << command_str << "'."
              << std::endl;
    return 1;
  }

  auto result = command_func_it->second(args);
  if (!result.ok()) {
    std::cerr << result.error().Message();
    return 1;
  }
  return result.value();
}

}  // namespace
}  // namespace cuttlefish

int main(int argc, char** argv) { return cuttlefish::DisplayMain(argc, argv); }
