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

#include <fuchsia/modular/cpp/fidl.h>

#include "gtest/gtest.h"
#include "peridot/bin/sessionmgr/puppet_master/puppet_master_impl.h"
#include "peridot/lib/testing/test_story_command_executor.h"
#include "peridot/lib/testing/test_with_session_storage.h"

namespace modular {
namespace {

class SessionCtlAppTest : public testing::TestWithSessionStorage {
 public:
  SessionCtlAppTest() {
    session_storage_ = MakeSessionStorage("page");
    puppet_master_impl_ = std::make_unique<PuppetMasterImpl>(
        session_storage_.get(), &test_executor_);
    puppet_master_impl_->Connect(puppet_master_.NewRequest());
    done_ = false;
  }

 protected:
  std::unique_ptr<SessionStorage> session_storage_;
  std::unique_ptr<PuppetMasterImpl> puppet_master_impl_;
  fuchsia::modular::PuppetMasterPtr puppet_master_;
  std::unique_ptr<Logger> logger_;
  testing::TestStoryCommandExecutor test_executor_;
  bool done_;

  SessionCtlApp CreateSessionCtl(fxl::CommandLine command_line) {
    logger_ =
        std::make_unique<Logger>(command_line.HasOption(kJsonOutFlagString));
    SessionCtlApp sessionctl(nullptr /* basemgr */, puppet_master_impl_.get(),
                             *(logger_.get()), async_get_default_dispatcher(),
                             [&] { done_ = true; });
    return sessionctl;
  }

  std::string RunLoopUntilCommandExecutes(
      fit::function<std::string()> command) {
    done_ = false;
    std::string error = command();

    RunLoopUntil([&] { return done_; });

    return error;
  }

  fuchsia::modular::internal::StoryDataPtr GetStoryData(
      const std::string& story_id) {
    fuchsia::modular::internal::StoryDataPtr sd;
    done_ = false;
    session_storage_->GetStoryData(story_id)->Then(
        [&](fuchsia::modular::internal::StoryDataPtr story_data) {
          sd = std::move(story_data);
          done_ = true;
        });
    RunLoopUntil([&] { return done_; });

    return sd;
  }
};

TEST_F(SessionCtlAppTest, GetUsage) {
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, "--mod_name=mod", "--story_name=story",
       "--mod_url=foo"});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);

  // Try to execute an invalid command
  std::string error = sessionctl.ExecuteCommand("fake_cmd", command_line);
  RunLoopUntilIdle();

  EXPECT_EQ(kGetUsageErrorString, error);
}

TEST_F(SessionCtlAppTest, AddMod) {
  // Add a mod
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, kAddModCommandString,
       "fuchsia-pkg://fuchsia.com/mod_url#meta/mod_url.cmx"});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
  });
  std::string default_name_hash = std::to_string(std::hash<std::string>{}(
      "fuchsia-pkg://fuchsia.com/mod_url#meta/mod_url.cmx"));

  // Assert the story and the mod were added with default story and mod names
  auto story_data = GetStoryData(default_name_hash);
  ASSERT_TRUE(story_data);
  EXPECT_EQ(default_name_hash, story_data->story_name());
  EXPECT_EQ(
      "fuchsia-pkg://fuchsia.com/mod_url#meta/mod_url.cmx",
      test_executor_.last_commands().at(0).add_mod().mod_name_transitional);
  EXPECT_EQ("fuchsia-pkg://fuchsia.com/mod_url#meta/mod_url.cmx",
            test_executor_.last_commands().at(0).add_mod().intent.handler);
  EXPECT_EQ(1, test_executor_.execute_count());
}

TEST_F(SessionCtlAppTest, AddModWithoutURL) {
  // Add a mod
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, kAddModCommandString, "mod_name"});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
  });
  std::string default_name_hash = std::to_string(std::hash<std::string>{}(
      "fuchsia-pkg://fuchsia.com/mod_name#meta/mod_name.cmx"));
  auto story_data = GetStoryData(default_name_hash);
  ASSERT_TRUE(story_data);
  EXPECT_EQ(default_name_hash, story_data->story_name());
  EXPECT_EQ("fuchsia-pkg://fuchsia.com/mod_name#meta/mod_name.cmx",
            test_executor_.last_commands().at(0).add_mod().intent.handler);
  EXPECT_EQ(1, test_executor_.execute_count());
}

TEST_F(SessionCtlAppTest, AddModWithColon) {
  // Add a mod
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, kAddModCommandString, "mod_name:0000"});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
  });
  std::string default_name_hash =
      std::to_string(std::hash<std::string>{}("mod_name:0000"));
  auto story_data = GetStoryData(default_name_hash);
  ASSERT_TRUE(story_data);
  EXPECT_EQ(default_name_hash, story_data->story_name());
  EXPECT_EQ("mod_name:0000",
            test_executor_.last_commands().at(0).add_mod().intent.handler);
  EXPECT_EQ(1, test_executor_.execute_count());
}

TEST_F(SessionCtlAppTest, AddModBadChars) {
  // Add a mod
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, kAddModCommandString, "a:bad/mod/name"});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
  });
  std::string default_name_hash =
      std::to_string(std::hash<std::string>{}("a:bad/mod/name"));

  auto story_data = GetStoryData(default_name_hash);
  ASSERT_TRUE(story_data);
  EXPECT_EQ(default_name_hash, story_data->story_name());
  EXPECT_EQ("a:bad/mod/name",
            test_executor_.last_commands().at(0).add_mod().intent.handler);
  EXPECT_EQ(1, test_executor_.execute_count());
}

TEST_F(SessionCtlAppTest, AddModWeb) {
  // Add a mod
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, kAddModCommandString, "https://www.google.com"});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
  });

  // Assert the story and the mod were added with default story and mod names
  std::string default_name_hash =
      std::to_string(std::hash<std::string>{}("https://www.google.com"));
  auto story_data = GetStoryData(default_name_hash);
  ASSERT_TRUE(story_data);
  EXPECT_EQ(default_name_hash, story_data->story_name());
  EXPECT_EQ(
      "https://www.google.com",
      test_executor_.last_commands().at(0).add_mod().mod_name_transitional);
  EXPECT_EQ("https://www.google.com",
            test_executor_.last_commands().at(0).add_mod().intent.handler);
  EXPECT_EQ(1, test_executor_.execute_count());
}

TEST_F(SessionCtlAppTest, AddModOverrideDefaults) {
  // Add a mod
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, "--story_name=s", "--mod_name=m",
       kAddModCommandString, "mod_url"});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
  });

  // Assert the story and the mod were added with overriden story and mod names
  auto story_name = "s";
  auto story_data = GetStoryData(story_name);
  ASSERT_TRUE(story_data);
  EXPECT_EQ(story_name, story_data->story_name());
  EXPECT_EQ(
      "m",
      test_executor_.last_commands().at(0).add_mod().mod_name_transitional);
  // mod_url becomes package
  EXPECT_EQ("fuchsia-pkg://fuchsia.com/mod_url#meta/mod_url.cmx",
            test_executor_.last_commands().at(0).add_mod().intent.handler);
  EXPECT_EQ(1, test_executor_.execute_count());
}

TEST_F(SessionCtlAppTest, AddModBadStoryName) {
  // Add a mod
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, "--story_name=??", "--mod_name=m",
       kAddModCommandString, "mod_url"});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);
  std::string error =
      sessionctl.ExecuteCommand(kAddModCommandString, command_line);
  RunLoopUntilIdle();
  EXPECT_EQ("Bad characters in story_name: ??", error);
}

TEST_F(SessionCtlAppTest, AddModMissingModUrl) {
  // Attempt to add a mod without a mod url
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, kAddModCommandString});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);
  std::string error =
      sessionctl.ExecuteCommand(kAddModCommandString, command_line);

  RunLoopUntilIdle();
  EXPECT_EQ("Missing MOD_URL. Ex: sessionctl add_mod slider_mod", error);
}

TEST_F(SessionCtlAppTest, RemoveMod) {
  // Add a mod
  auto mod = "mod";
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, kAddModCommandString, mod});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
  });

  // Remove the mod
  command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, kRemoveModCommandString, mod});
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kRemoveModCommandString, command_line);
  });

  // Assert session_storage still contains the story
  auto story_data = GetStoryData(mod);
  ASSERT_TRUE(story_data);
  EXPECT_EQ(mod, story_data->story_name());
  EXPECT_EQ(
      mod,
      test_executor_.last_commands().at(0).remove_mod().mod_name_transitional);
  EXPECT_EQ(2, test_executor_.execute_count());
}

TEST_F(SessionCtlAppTest, RemoveModOverrideDefault) {
  // Add a mod with overridden story and mod names
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, "--story_name=s", "--mod_name=m",
       kAddModCommandString, "mod"});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
  });

  // Remove the mod with an overridden story name
  auto mod_name = "m";
  command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, "--story_name=s", kRemoveModCommandString, mod_name});
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kRemoveModCommandString, command_line);
  });

  // Assert session_storage still contains the story
  auto story_name = "s";
  auto story_data = GetStoryData(story_name);
  ASSERT_TRUE(story_data);
  EXPECT_EQ(story_name, story_data->story_name());
  EXPECT_EQ(
      mod_name,
      test_executor_.last_commands().at(0).remove_mod().mod_name_transitional);
  EXPECT_EQ(2, test_executor_.execute_count());
}

TEST_F(SessionCtlAppTest, RemoveModMissingModName) {
  // Attempt to remove a mod without a mod name
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, kRemoveModCommandString});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);
  std::string error =
      sessionctl.ExecuteCommand(kRemoveModCommandString, command_line);

  RunLoopUntilIdle();
  EXPECT_EQ("Missing MOD_NAME. Ex: sessionctl remove_mod slider_mod", error);
}

TEST_F(SessionCtlAppTest, DeleteStory) {
  // Add a mod with overridden story name
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, "--story_name=story", kAddModCommandString, "mod"});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
  });

  // Remove the story
  auto story_name = "story";
  command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, kDeleteStoryCommandString, story_name});
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kDeleteStoryCommandString, command_line);
  });

  auto story_data = GetStoryData(story_name);
  EXPECT_FALSE(story_data);
  EXPECT_EQ(1, test_executor_.execute_count());
}

TEST_F(SessionCtlAppTest, DeleteStoryMissingStoryName) {
  // Attempt to delete a story without the required flags
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, kDeleteStoryCommandString});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);
  std::string error =
      sessionctl.ExecuteCommand(kDeleteStoryCommandString, command_line);

  RunLoopUntilIdle();
  EXPECT_EQ("Missing STORY_NAME. Ex. sessionctl delete_story story", error);
}

TEST_F(SessionCtlAppTest, DeleteAllStories) {
  // Add two mods
  auto mod1 = "mod1";
  auto story1 = std::to_string(
      std::hash<std::string>{}("fuchsia-pkg://fuchsia.com/mod1#meta/mod1.cmx"));
  auto command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, kAddModCommandString, mod1});
  SessionCtlApp sessionctl = CreateSessionCtl(command_line);
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
  });

  auto mod2 = "mod2";
  auto story2 = std::to_string(
      std::hash<std::string>{}("fuchsia-pkg://fuchsia.com/mod2#meta/mod2.cmx"));
  command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, kAddModCommandString, mod2});
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
  });

  EXPECT_TRUE(GetStoryData(story1));
  EXPECT_TRUE(GetStoryData(story2));

  // Delete all stories
  command_line = fxl::CommandLineFromInitializerList(
      {kSessionCtlString, kDeleteAllStoriesCommandString});
  RunLoopUntilCommandExecutes([&] {
    return sessionctl.ExecuteCommand(kDeleteAllStoriesCommandString,
                                     command_line);
  });

  EXPECT_FALSE(GetStoryData(story1));
  EXPECT_FALSE(GetStoryData(story2));
}

}  // namespace
}  // namespace modular
