// 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.

#ifndef PERIDOT_BIN_SESSIONCTL_SESSION_CTL_APP_H_
#define PERIDOT_BIN_SESSIONCTL_SESSION_CTL_APP_H_

#include <iostream>
#include <string>

#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/fxl/command_line.h>
#include <lib/fxl/strings/string_printf.h>
#include "lib/fxl/functional/make_copyable.h"
#include "peridot/bin/sessionctl/logger.h"

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

namespace modular {

class SessionCtlApp {
 public:
  // Constructs a SessionCtlApp which can read and execute session commands.
  // |puppet_master| The interface used to execute commands.
  // |basemgr| The basemgr to use to restart sessions.
  // |command_line| The command line used to read commands and arguments.
  // |logger| The logger used to log the results of commands.
  // |dispatcher| The dispatcher which is used to post the command tasks.
  // |on_command_executed| A callback which is called whenever a command has
  // finished executing.
  explicit SessionCtlApp(
      fuchsia::modular::internal::BasemgrDebug* const basemgr,
      fuchsia::modular::PuppetMaster* const puppet_master,
      const modular::Logger& logger, async_dispatcher_t* const dispatcher,
      const std::function<void()>& on_command_executed);

  // Dispatches the |cmd| and returns an empty string on success, "GetUsage" if
  // |cmd| is not valid, and a string of missing flags on failure.
  std::string ExecuteCommand(std::string cmd,
                             const fxl::CommandLine& command_line);

 private:
  // Executes the respective command and returns an empty string on success and
  // a string of missing flags on failure.
  std::string ExecuteAddModCommand(const fxl::CommandLine& command_line);
  std::string ExecuteRemoveModCommand(const fxl::CommandLine& command_line);
  std::string ExecuteDeleteStoryCommand(const fxl::CommandLine& command_line);
  std::string ExecuteListStoriesCommand();
  std::string ExecuteRestartSessionCommand();

  // Focus the story to which the mod we are adding belongs.
  fuchsia::modular::StoryCommand MakeFocusStoryCommand();

  // Focus the mod we just added. This is not necessary when adding a new mod
  // since it will be always focused. However, when a mod is updated it might
  // not be focused.
  fuchsia::modular::StoryCommand MakeFocusModCommand(
      const std::string& mod_name);

  std::vector<fuchsia::modular::StoryCommand> MakeAddModCommands(
      const std::string& mod_url, const std::string& mod_name);

  std::vector<fuchsia::modular::StoryCommand> MakeRemoveModCommands(
      const std::string& mod_name);

  // Does a PostTask to Execute the commands on StoryPuppetMaster.
  // When the commands are executed do logging and then call
  // on_command_executed_() callback.
  // |command_name| the string command name.
  // |commands| the StoryCommands to execute on StoryPuppetMaster.
  // |params| map of {command_line arg : command_line value}. Used for logging.
  void PostTaskExecuteStoryCommand(
      const std::string command_name,
      std::vector<fuchsia::modular::StoryCommand> commands,
      std::map<std::string, std::string> params);

  modular::FuturePtr<bool, std::string> ExecuteStoryCommand(
      std::vector<fuchsia::modular::StoryCommand> commands,
      const std::string& story_name);

  std::string GenerateMissingFlagString(
      const std::vector<std::string>& missing_flags);

  fuchsia::modular::internal::BasemgrDebug* const basemgr_;
  fuchsia::modular::PuppetMaster* const puppet_master_;
  fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;
  const fxl::CommandLine command_line_;
  const modular::Logger logger_;
  async_dispatcher_t* const dispatcher_;
  const std::function<void()> on_command_executed_;
};

}  // namespace modular

#endif  // PERIDOT_BIN_SESSIONCTL_SESSION_CTL_APP_H_
