/*
 * Copyright 2022 NWChemEx-Project
 *
 * Licensed 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.
 */

#include "../catch.hpp"
#include "../test_common.hpp"
#include "pluginplay/printing/document_module.hpp"

using namespace pluginplay::printing;
using namespace testing;

TEST_CASE("document_module") {
    SECTION("Empty module") {
        auto m = make_module<NullModule>();
        auto corr =
          "..   This page is autogenerated by pluginplay::document_module. Any"
          " changes made\n"
          "..   to this document will be overwritten the next time it "
          "is generated.\n"
          "\n"
          "############\n"
          "empty module\n"
          "############\n"
          "\n"
          "No description provided\n"
          "\n"
          "***********\n"
          "Please Cite\n"
          "***********\n"
          "\n"
          "No citations\n"
          "\n"
          "**************\n"
          "Property Types\n"
          "**************\n"
          "\n"
          "The following is a list of property types that this module"
          " satisfies.\n"
          "\n"
          "- ``testing::NullPT``\n"
          "\n"
          "*************\n"
          "Module Inputs\n"
          "*************\n"
          "\n"
          "This section details the full list of inputs that the "
          "module accepts. Inputs\n"
          "that are not listed as optional must have their value set "
          "before the module can\n"
          "be run. Inputs can be set manually by calling the module's"
          " ``change_input``\n"
          "function or by passing arguments to a property type.\n"
          "\n"
          "Quick Reference\n"
          "===============\n"
          "\n"
          "The module defines no inputs.\n"
          "\n"
          "Detailed Descriptions\n"
          "=====================\n"
          "\n"
          "The module defines no inputs.\n"
          "\n"
          "**************\n"
          "Module Results\n"
          "**************\n"
          "\n"
          "The module defines no results.\n"
          "\n"
          "**********\n"
          "Submodules\n"
          "**********\n"
          "\n"
          "The module defines no submodules.\n"
          "\n";
        REQUIRE(document_module("empty module", *m) == corr);
    }
    SECTION("The whole shebang") {
        auto m = make_module<RealDeal>();
        auto corr =
          "..   This page is autogenerated by "
          "pluginplay::document_module. Any changes made\n"
          "..   to this document will be overwritten the next time it "
          "is generated.\n"
          "\n"
          "#########\n"
          "For Reals\n"
          "#########\n"
          "\n"
          "This module is the real deal. It does math stuff like:\n"
          "\n"
          ".. math::\n"
          "\n"
          "   \\sum_{i=0}^N i = \\frac{N(N+1)}{2}\n"
          "\n"
          "Okay it's not that cool...\n"
          "\n"
          "***********\n"
          "Please Cite\n"
          "***********\n"
          "\n"
          "- A. Person. *The Best Article*. A Journal You Have Never "
          "Heard Of. 1 (2008).\n"
          "- B. Person. *A So-So Article*. A Journal Everyone Has "
          "HeardOf. 1 (2009).\n"
          "\n"
          "\n"
          "**************\n"
          "Property Types\n"
          "**************\n"
          "\n"
          "The following is a list of property types that this "
          "module satisfies.\n"
          "\n"
          "- ``testing::NullPT``\n"
          "- ``testing::OneIn``\n"
          "- ``testing::OneOut``\n"
          "\n"
          "*************\n"
          "Module Inputs\n"
          "*************\n"
          "\n"
          "This section details the full list of inputs that the "
          "module accepts. Inputs\n"
          "that are not listed as optional must have their value set "
          "before the module can\n"
          "be run. Inputs can be set manually by calling the "
          "module's ``change_input``\n"
          "function or by passing arguments to a property type.\n"
          "\n"
          "Quick Reference\n"
          "===============\n"
          "\n"
          "The following table provides a quick summary of the "
          "inputs available to this\n"
          "module. The columns are:\n"
          "\n"
          "- ``Key``: The key used to retrieve the option,\n"
          "- ``Default`` : The initial value, if one exists, and\n"
          "- ``Description`` : A human readable description of what "
          "the option is used for.\n"
          "\n"
          "+----------+---------+-------------+\n"
          "| Key      | Default | Description |\n"
          "+==========+=========+=============+\n"
          "| Option 1 | N/A     | N/A         |\n"
          "+----------+---------+-------------+\n"
          "\n"
          "\n"
          "Detailed Descriptions\n"
          "=====================\n"
          "\n"
          "The following subsections provide detailed descriptions "
          "of each input recognized\n"
          "by this module. The subsection headings are the name of "
          "the input. Within each\n"
          "subsection we list:\n"
          "\n"
          "- ``Description`` : A human readable description of what "
          "the option is used for.\n"
          "- ``Default Value`` : The initial value, if one exists.\n"
          "- ``Optional?`` : Whether the value must be set inorder "
          "for the module to run.\n"
          "- ``Opaque?`` : Does the value of the input influence "
          "memoization?.\n"
          "- ``Domain Restrictions`` : Criteria a value must obey to "
          "be deemed valid.\n"
          "\n"
          "Option 1\n"
          "--------\n"
          "\n"
          "- Description : N/A\n"
          "- Default Value : N/A\n"
          "- Optional? : False\n"
          "- Opaque? : True\n"
          "- Domain Restrictions :\n"
          "\n"
          "  - Type == int\n"
          "\n"
          "\n"
          "**************\n"
          "Module Results\n"
          "**************\n"
          "\n"
          "This section tabulates the full list of results that the "
          "module returns. The\n"
          "columns respectively are:\n"
          "\n"
          "- Key: What the result is called\n"
          "- Type: The C++ type of the result\n"
          "- Description: What the result is/how it was computed.\n"
          "\n"
          ".. note::\n"
          "\n"
          "   A given property type will only return a subset of the "
          "available results. \n"
          "   Additional results can be accessed by using other "
          "property types or by using\n"
          "   the Module class's advanced API.\n"
          "\n"
          "+----------+------+-------------+\n"
          "| Key      | Type | Description |\n"
          "+==========+======+=============+\n"
          "| Result 1 | int  | N/A         |\n"
          "+----------+------+-------------+\n"
          "\n"
          "\n"
          "**********\n"
          "Submodules\n"
          "**********\n"
          "\n"
          "The module defines no submodules.\n\n";

        REQUIRE(document_module("For Reals", *m) == corr);
    }
}
