// Copyright 2018 The Fuchsia 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 <dirent.h>
#include <fuchsia/modular/cpp/fidl.h>
#include <fuchsia/modular/internal/cpp/fidl.h>
#include <glob.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/future.h>
#include <lib/async/cpp/task.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <src/lib/fxl/command_line.h>
#include <src/lib/fxl/log_settings_command_line.h>
#include <src/lib/fxl/strings/string_printf.h>
#include <sys/types.h>

#include <chrono>
#include <iostream>
#include <regex>
#include <string>
#include <thread>
#include <vector>

#include "peridot/bin/sessionctl/logger.h"
#include "peridot/bin/sessionctl/session_ctl_app.h"
#include "peridot/bin/sessionctl/session_ctl_constants.h"
#include "src/lib/files/file.h"

using ::fuchsia::modular::PuppetMaster;
using ::fuchsia::modular::PuppetMasterPtr;

struct DebugService {
  std::string name;
  std::string service_path;
};

std::string GetUsage() {
  return R"(sessionctl <flags> <command> <argument>
Example:
sessionctl add_mod slider_mod

sessionctl --mod_name=mod1 --story_name=story1 --focus_mod=false
            --focus_story=false add_mod slider_mod

sessionctl --story_name=story1 remove_mod slider_mod

<flags>
--story_name=STORY_NAME
--mod_name=MOD_NAME
--focus_mod=false
    Don't focus the mod.
--focus_story=false
    Don't focus the story.
--json_out
    If flag is set output json for consuming instead of text.
--wait_for_session
    Blocks progress on completing a command until a guest user is logged in.

<command>
add_mod
  Usage: [--story_name=foo] [--mod_name=bar] [--focus_mod=false] [--focus_story=false] add_mod MOD_URL

  Add a new mod or update an existing mod if a mod with --mod_name already
  exists in --story_name.
  Defaults --story_name and --mod_name to MOD_URL.
  Defaults --focus_mod and --focus_story to 'true'.

  MOD_URL
    This can be either the mod's full package url or the mod component's name.
    The mod components name will be converted to the following package url
    format: fuchsia-pkg://fuchsia.com/MOD_URL#meta/MOD_URL.cmx.

  optional: --story_name, --mod_name, --focus_mod, --focus_story

remove_mod
  Usage: [--story_name=foo] remove_mod MOD_NAME

  Removes an existing mod by name. If the mod was added with add_mod,
  use the value you passed to add_mod's --mod_name flag or the default
  value which would be the mod_url.
  Defaults --story_name to MOD_NAME.

  MOD_NAME
    The name of the mod.

  optional: --story_name

delete_story
  Usage: delete_story STORY_NAME

  Deletes the story.

  STORY_NAME
    The name of the story.

delete_all_stories
  Deletes all stories in the current session.

list_stories
  List all the stories in the current session.

login_guest
  Logs in a guest user.

restart_session
  Restarts the current session.

next_session_shell
  Toggles to the next defined session shell.

help
  Lists the available commands.)";
}

void FindDebugServicesForPath(const char* glob_str, const char* regex_str,
                              std::vector<DebugService>* services) {
  glob_t globbuf;
  bool service_exists = glob(glob_str, 0, nullptr, &globbuf) == 0;
  std::regex name_regex(regex_str);
  if (service_exists) {
    for (size_t i = 0; i < globbuf.gl_pathc; ++i) {
      DebugService s;
      s.service_path = globbuf.gl_pathv[i];
      std::smatch match;
      FXL_CHECK(std::regex_search(s.service_path, match, name_regex))
          << s.service_path;
      s.name = match[1];
      services->push_back(std::move(s));
    }
    globfree(&globbuf);
  }
}

// Returns a list of all running sessions.
std::vector<DebugService> FindAllSessions() {
  const char kRegex[] = "/sessionmgr.cmx/(\\d+)";
  // See peridot/bin/sessionmgr/sessionmgr_impl.cc's definition of
  // kSessionCtlDir for "sessionctl". These must match.
  std::vector<DebugService> sessions;
  FindDebugServicesForPath(modular::kSessionCtlServiceGlobPath, kRegex,
                           &sessions);

  // Path to sessionctl service from a virtual console
  FindDebugServicesForPath(
      "/hub/r/sys/*/c/sessionmgr.cmx/*/out/debug/sessionctl", kRegex,
      &sessions);
  return sessions;
}

PuppetMasterPtr ConnectToPuppetMaster(const DebugService& session) {
  PuppetMasterPtr puppet_master;
  auto request = puppet_master.NewRequest().TakeChannel();
  std::string service_path = session.service_path + "/" + PuppetMaster::Name_;
  if (fdio_service_connect(service_path.c_str(), request.get()) != ZX_OK) {
    FXL_LOG(FATAL) << "Could not connect to PuppetMaster service in "
                   << session.service_path;
  }
  return puppet_master;
}

fuchsia::modular::internal::BasemgrDebugPtr ConnectToBasemgr() {
  const char kRegex[] = "/basemgr.cmx/(\\d+)";
  std::vector<DebugService> services;
  FindDebugServicesForPath(modular::kBasemgrDebugServiceGlobPath, kRegex,
                           &services);

  // Path to basemgr debug service from a virtual console
  FindDebugServicesForPath("/hub/r/sys/*/c/basemgr.cmx/*/out/debug/basemgr",
                           kRegex, &services);

  if (services.empty()) {
    return nullptr;
  }
  FXL_CHECK(services.size() == 1);
  std::string service_path = services[0].service_path;

  fuchsia::modular::internal::BasemgrDebugPtr basemgr;
  auto request = basemgr.NewRequest().TakeChannel();
  if (fdio_service_connect(service_path.c_str(), request.get()) != ZX_OK) {
    FXL_LOG(FATAL) << "Could not connect to basemgr service in "
                   << service_path;
  }

  return basemgr;
}

// Returns true if a guest user was logged in.
bool LoginAsGuest(bool has_running_sessions,
                  fuchsia::modular::internal::BasemgrDebug* basemgr,
                  modular::Logger logger) {
  if (has_running_sessions) {
    logger.LogError(modular::kLoginGuestCommandString,
                    "A user is already logged in. You may log a guest user out "
                    "by running 'sessionctl restart_session' or you may issue "
                    "any other sessionctl command.");
    return false;
  }

  basemgr->LoginAsGuest();
  logger.Log(modular::kLoginGuestCommandString, std::vector<std::string>());
  return true;
}

// Returns true if a guest user was logged in.
bool LoginDefaultGuestUser(fuchsia::modular::internal::BasemgrDebug* basemgr,
                           modular::Logger logger,
                           std::vector<DebugService>* sessions, std::string cmd,
                           bool wait_for_session) {
  std::cout << "Logging in as a guest user in the absence of running sessions."
            << std::endl;
  LoginAsGuest(/*has_running_sessions=*/false, basemgr, logger);

  do {
    // Wait 2 seconds to allow sessionmgr to initialize
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::cout << "Finding sessions..." << std::endl;
    *sessions = FindAllSessions();
  } while (wait_for_session && sessions->empty());

  if (sessions->empty()) {
    logger.LogError(cmd,
                    "Unable find a running session after logging in. "
                    "Please try your command again.");
    return false;
  }

  return true;
}

int main(int argc, const char** argv) {
  async::Loop loop(&kAsyncLoopConfigAttachToThread);

  const auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
  fxl::SetLogSettingsFromCommandLine(command_line);
  const auto& positional_args = command_line.positional_args();
  const auto& cmd = positional_args.empty() ? "" : positional_args[0];

  if (cmd == modular::kHelpCommandString || cmd.empty()) {
    std::cout << GetUsage() << std::endl;
    return 1;
  }

  const modular::Logger logger(
      command_line.HasOption(modular::kJsonOutFlagString));

  auto basemgr = ConnectToBasemgr();
  if (!basemgr) {
    logger.LogError(cmd, "Could not find a running basemgr. Is it running?");
    return 1;
  }

  auto sessions = FindAllSessions();

  // Continue with log in flow if user issued a login_guest command
  if (cmd == modular::kLoginGuestCommandString) {
    if (LoginAsGuest(/*has_running_sessions=*/!sessions.empty(), basemgr.get(),
                     logger)) {
      return 0;
    }
    return 1;
  }

  // Log in a guest user if no session is found before continuing to execute
  // the requested command
  if (sessions.empty()) {
    if (cmd == modular::kRestartSessionCommandString) {
      logger.LogError(cmd, "No session to be restarted.");
      return 1;
    }

    bool wait_for_session =
        command_line.HasOption(modular::kWaitForSessionFlagString);

    // Exit here if no sessions were found after logging in a guest user
    if (!LoginDefaultGuestUser(basemgr.get(), logger, &sessions, cmd,
                               wait_for_session)) {
      return 1;
    }
  }

  if (!command_line.HasOption(modular::kJsonOutFlagString)) {
    std::cout << "Found the following sessions:\n\n";
    for (const auto& session : sessions) {
      std::cout << "\t" << session.name << ": " << session.service_path
                << std::endl;
    }
    std::cout << std::endl;
  }

  // To get a PuppetMaster service for a session, use the following code:
  PuppetMasterPtr puppet_master = ConnectToPuppetMaster(sessions[0]);

  modular::SessionCtlApp app(basemgr.get(), puppet_master.get(), logger,
                             loop.dispatcher(), [&loop] { loop.Quit(); });

  std::string parsing_error = app.ExecuteCommand(cmd, command_line);
  if (parsing_error == modular::kGetUsageErrorString) {
    // Print help if command doesn't match a valid command.
    std::cout << GetUsage() << std::endl;
    return 1;
  }

  if (!parsing_error.empty()) {
    return 1;
  }

  loop.Run();

  return 0;
}
