/** @file

  Unit tests for a class that deals with plugin Dynamic Shared Objects (DSO)

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.

  @section details Details

  Implements code necessary for Reverse Proxy which mostly consists of
  general purpose hostname substitution in URLs.

 */

#define CATCH_CONFIG_MAIN /* include main function */
#include <catch.hpp>      /* catch unit-test framework */
#include <fstream>        /* ofstream */

#include "plugin_testing_common.h"
#include "../PluginDso.h"

class PluginContext;
thread_local PluginThreadContext *pluginThreadContext;

std::error_code ec;

/* The following are dirs that are used commonly in the unit-tests */
static fs::path sandboxDir     = getTemporaryDir();
static fs::path runtimeDir     = sandboxDir / fs::path("runtime");
static fs::path searchDir      = sandboxDir / fs::path("search");
static fs::path pluginBuildDir = fs::current_path() / fs::path("unit-tests/.libs");

/* The following are paths used in all scenarios in the unit tests */
static fs::path configPath      = fs::path("plugin_v1.so");
static fs::path pluginBuildPath = pluginBuildDir / configPath;
static fs::path effectivePath   = searchDir / configPath;
static fs::path runtimePath     = runtimeDir / configPath;

void
clean()
{
  fs::remove(sandboxDir, ec);
}

/* Mock used only to make PluginDso concrete enough to be tested */
class PluginDsoUnitTest : public PluginDso
{
public:
  PluginDsoUnitTest(const fs::path &configPath, const fs::path &effectivePath, const fs::path &runtimePath)
    : PluginDso(configPath, effectivePath, runtimePath)
  {
    /* don't remove runtime DSO copy preventively so we can check if it was created properly */
    _preventiveCleaning = false;
  }

  virtual void
  indicatePreReload()
  {
  }
  virtual void
  indicatePostReload(TSRemapReloadStatus reloadStatus)
  {
  }
  virtual bool
  init(std::string &error)
  {
    return true;
  }
  virtual void
  done()
  {
  }
};

/*
 * The following scenario tests loading and unloading of plugins
 */
SCENARIO("loading plugins", "[plugin][core]")
{
  REQUIRE_FALSE(sandboxDir.empty());

  clean();
  std::string error;

  GIVEN("a valid plugin")
  {
    /* Setup the test fixture - search, runtime dirs and install a plugin with some defined callback functions */
    CHECK(fs::create_directories(searchDir, ec));
    CHECK(fs::create_directories(runtimeDir, ec));
    fs::copy(pluginBuildPath, searchDir, ec);

    /* Instantiate and initialize a plugin DSO instance. Make sure effective path exists, used to load */
    CHECK(fs::exists(effectivePath));
    PluginDsoUnitTest plugin(configPath, effectivePath, runtimePath);

    WHEN("loading a valid plugin")
    {
      bool result = plugin.load(error);

      THEN("expect it to successfully load")
      {
        CHECK(true == result);
        CHECK(error.empty());
        CHECK(effectivePath == plugin.effectivePath());
        CHECK(runtimePath == plugin.runtimePath());
        CHECK(fs::exists(runtimePath));
      }
      CHECK(fs::remove(sandboxDir, ec));
    }

    WHEN("loading a valid plugin")
    {
      bool result = plugin.load(error);

      THEN("expect saving the right DSO file modification time")
      {
        CHECK(true == result);
        CHECK(error.empty());
        std::error_code ec;
        fs::file_status fs = fs::status(effectivePath, ec);
        CHECK(plugin.modTime() == fs::modification_time(fs));
      }
      CHECK(fs::remove(sandboxDir, ec));
    }

    WHEN("loading a valid plugin but missing runtime dir")
    {
      CHECK(fs::remove(runtimeDir, ec));
      CHECK_FALSE(fs::exists(runtimePath));
      bool result = plugin.load(error);

      THEN("expect it to fail")
      {
        CHECK_FALSE(true == result);
        CHECK("failed to create a copy: No such file or directory" == error);
      }
      CHECK(fs::remove(sandboxDir, ec));
    }

    WHEN("loading a valid plugin twice in a row")
    {
      /* First attempt OK */
      bool result = plugin.load(error);
      CHECK(true == result);
      CHECK(error.empty());

      /* Second attempt */
      result = plugin.load(error);

      THEN("expect it to fail the second attempt")
      {
        CHECK_FALSE(true == result);
        CHECK("plugin already loaded" == error);
      }
      CHECK(fs::remove(sandboxDir, ec));
    }

    WHEN("explicitly unloading a valid but not loaded plugin")
    {
      /* Make sure it is not loaded, runtime DSO not present */
      CHECK_FALSE(fs::exists(runtimePath));

      /* Unload w/o loading beforehand */
      bool result = plugin.unload(error);

      THEN("expect the unload to fail")
      {
        CHECK(false == result);
        CHECK_FALSE(error.empty());
        CHECK_FALSE(fs::exists(runtimePath));
      }
      CHECK(fs::remove(sandboxDir, ec));
    }

    WHEN("unloading a valid plugin twice in a row")
    {
      /* First attempt OK */
      bool result = plugin.load(error);
      CHECK(true == result);
      CHECK(error.empty());
      result = plugin.unload(error);
      CHECK(true == result);
      CHECK("" == error);

      /* Second attempt */
      result = plugin.unload(error);

      THEN("expect it to fail the second attempt")
      {
        CHECK_FALSE(true == result);
        CHECK("no plugin loaded" == error);
      }
      CHECK(fs::remove(sandboxDir, ec));
    }

    WHEN("explicitly unloading a valid and loaded plugin")
    {
      /* Make sure it is not loaded, runtime DSO not present */
      CHECK_FALSE(fs::exists(runtimePath));

      /* Load and make sure it is loaded */
      CHECK(plugin.load(error));
      /* Effective and runtime path set */
      CHECK(effectivePath == plugin.effectivePath());
      CHECK(runtimePath == plugin.runtimePath());
      /* Runtime DSO should be present */
      CHECK(fs::exists(runtimePath));

      /* Unload */
      bool result = plugin.unload(error);

      THEN("expect it to successfully unload")
      {
        CHECK(true == result);
        CHECK(error.empty());
        /* Effective and runtime path still set */
        CHECK(effectivePath == plugin.effectivePath());
        CHECK(runtimePath == plugin.runtimePath());
        /* Runtime DSO should not be found anymore */
        CHECK_FALSE(fs::exists(runtimePath));
      }
      CHECK(fs::remove(sandboxDir, ec));
    }

    WHEN("implicitly unloading a valid and loaded plugin")
    {
      {
        PluginDsoUnitTest localPlugin(configPath, effectivePath, runtimePath);

        /* Load and make sure it is loaded */
        CHECK(localPlugin.load(error));
        /* Effective and runtime path set */
        CHECK(effectivePath == localPlugin.effectivePath());
        CHECK(runtimePath == localPlugin.runtimePath());
        /* Runtime DSO should be present */
        CHECK(fs::exists(runtimePath));

        /* Unload by going out of scope */
      }

      THEN("expect it to successfully unload and clean after itself")
      {
        /* Runtime path should be removed after unloading */
        CHECK_FALSE(fs::exists(runtimePath));
      }
      CHECK(fs::remove(sandboxDir, ec));
    }
  }

  GIVEN("a plugin instance initialized with an empty effective path")
  {
    std::string error;
    PluginDsoUnitTest plugin(configPath, /* effectivePath */ fs::path(), runtimePath);

    WHEN("loading the plugin")
    {
      bool result = plugin.load(error);

      THEN("expect the load to fail")
      {
        CHECK_FALSE(true == result);
        CHECK("empty effective path" == error);
        CHECK(plugin.effectivePath().empty());
        CHECK(0 == plugin.modTime());
        CHECK(runtimePath == plugin.runtimePath());
        CHECK_FALSE(fs::exists(runtimePath));
      }
    }
  }

  GIVEN("an invalid plugin")
  {
    /* Create the directory structure and install plugins */
    CHECK(fs::create_directories(searchDir, ec));
    CHECK(fs::create_directories(runtimeDir, ec));
    /* Create an invalid plugin and make sure the effective path to it exists */
    std::ofstream file(effectivePath.string());
    file << "Invalid plugin DSO content";
    file.close();
    CHECK(fs::exists(effectivePath));

    /* Instantiate and initialize a plugin DSO instance. */
    std::string error;
    PluginDsoUnitTest plugin(configPath, effectivePath, runtimePath);

    WHEN("loading an invalid plugin")
    {
      bool result = plugin.load(error);

      THEN("expect it to fail to load")
      {
        /* After calling load() the following should be set correctly */
        CHECK(effectivePath == plugin.effectivePath());
        CHECK(runtimePath == plugin.runtimePath());

        /* But the load should fail and an error should be returned */
        CHECK(false == result);
        CHECK_FALSE(error.empty());

        /* Runtime DSO should not exist since the load failed. */
        CHECK_FALSE(fs::exists(runtimePath));
      }
      CHECK(fs::remove(sandboxDir, ec));
    }
  }
}

/*
 * The following scenario tests finding symbols inside the DSO.
 */
SCENARIO("looking for symbols inside a plugin DSO", "[plugin][core]")
{
  REQUIRE_FALSE(sandboxDir.empty());

  clean();
  std::string error;

  /* Setup the test fixture - search, runtime dirs and install a plugin with some defined callback functions */
  CHECK(fs::create_directories(searchDir, ec));
  CHECK(fs::create_directories(runtimeDir, ec));
  fs::copy(pluginBuildDir / configPath, searchDir, ec);

  /* Initialize a plugin DSO instance */
  PluginDsoUnitTest plugin(configPath, effectivePath, runtimePath);

  /* Now test away. */
  GIVEN("plugin loaded successfully")
  {
    CHECK(plugin.load(error));

    WHEN("looking for an existing symbol")
    {
      THEN("expect to find it")
      {
        void *s = nullptr;
        CHECK(plugin.getSymbol("TSRemapInit", s, error));
        CHECK(nullptr != s);
        CHECK(error.empty());
      }
      CHECK(fs::remove(sandboxDir, ec));
    }

    WHEN("looking for non-existing symbol")
    {
      THEN("expect not to find it and get an error")
      {
        void *s = nullptr;
        CHECK_FALSE(plugin.getSymbol("NONEXISTING_SYMBOL", s, error));
        CHECK(nullptr == s);
        CHECK_FALSE(error.empty());
      }
      CHECK(fs::remove(sandboxDir, ec));
    }

    WHEN("looking for multiple existing symbols")
    {
      THEN("expect to find them all")
      {
        std::vector<const char *> list{"TSRemapInit",           "TSRemapDone",       "TSRemapDoRemap", "TSRemapNewInstance",
                                       "TSRemapDeleteInstance", "TSRemapOSResponse", "TSPluginInit",   "pluginDsoVersionTest"};
        for (auto symbol : list) {
          void *s = nullptr;
          CHECK(plugin.getSymbol(symbol, s, error));
          CHECK(nullptr != s);
          CHECK(error.empty());
        }
      }
      CHECK(fs::remove(sandboxDir, ec));
    }

    /* The following version function is used only for unit-testing of the plugin factory functionality */
    WHEN("using a symbol to call the corresponding version function")
    {
      THEN("expect to return the version number")
      {
        void *s = nullptr;
        CHECK(plugin.getSymbol("pluginDsoVersionTest", s, error));
        int (*version)() = reinterpret_cast<int (*)()>(s);
        int ver          = version ? version() : -1;
        CHECK(1 == ver);
      }
      CHECK(fs::remove(sandboxDir, ec));
    }
  }
}
