// 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 <glob.h>
#include <sys/types.h>
#include <chrono>
#include <iostream>
#include <regex>
#include <string>
#include <thread>
#include <vector>

#include <fuchsia/modular/cpp/fidl.h>
#include <fuchsia/modular/internal/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/future.h>
#include <lib/async/cpp/task.h>
#include <lib/fdio/util.h>
#include <lib/fxl/command_line.h>
#include <lib/fxl/files/file.h>
#include <lib/fxl/log_settings_command_line.h>
#include <lib/fxl/strings/string_printf.h>
#include "lib/fxl/functional/make_copyable.h"

#include "peridot/bin/sessionctl/logger.h"
#include "peridot/bin/sessionctl/session_ctl_app.h"
#include "peridot/bin/sessionctl/session_ctl_constants.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.

<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
    Mods have a unique "mod_url". It's the mod package's name.
    In BUILD.gn fuchsia_package_name = "mod_url" or mod_url comes from
    flutter_app("mod_url") when there is no fuchsia_package_name set.

  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.

list_stories
  List all the stories in the current session.

login_guest
  Logs in a guest user.

restart_session
  Restarts the current session.)";
}

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) {
  std::cout << "Logging in as a guest user in the absence of running sessions."
            << std::endl;
  LoginAsGuest(/*has_running_sessions=*/false, basemgr, logger);

  // 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();

  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];

  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()) {
    // Exit here if no sessions were found after logging in a guest user
    if (!LoginDefaultGuestUser(basemgr.get(), logger, &sessions, cmd)) {
      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;
}
