/*
 * 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 "detail_/print_inputs.hpp"
#include "detail_/print_results.hpp"
#include "detail_/print_submodules.hpp"
#include "detail_/rest_printer.hpp"
#include "pluginplay/printing/document_module.hpp"
#include <sstream>
#include <utilities/printing/demangler.hpp>
#include <utilities/printing/word_wrap_stream.hpp>

namespace pluginplay::printing {

std::string document_module(std::string name, const Module& mod) {
    std::stringstream ss;
    detail_::reSTPrinter p(ss);

    p << "..   This page is autogenerated by pluginplay::document_module. Any "
         "changes made\n";
    p << "..   to this document will be overwritten the next time it is "
         "generated.\n\n";

    p.start_section(name);
    p << "\n";
    if(mod.has_description()) {
        p << mod.description();
    } else {
        p << "No description provided";
    }
    p << "\n\n";

    p.start_section("Please Cite");
    p << "\n";
    if(mod.citations().empty()) {
        p << "No citations";
    } else {
        for(const auto& x : mod.citations()) p << "- " << x << "\n";
    }
    p << "\n\n";
    p.finish_section();

    p.start_section("Property Types");
    p << "\n";
    if(mod.property_types().empty()) {
        p << "The module satisfies no property types.\n\n";
    } else {
        p << "The following is a list of property types that this module "
             "satisfies.\n\n";
        std::set<std::string> pt_set;
        for(const auto& x : mod.property_types()) {
            std::string pt_string =
              "- ``" + utilities::printing::Demangler::demangle(x) + "``\n";
            pt_set.insert(pt_string);
        }
        for(const auto& x : pt_set) { p.print_verbatim(x); }
    }
    p << "\n";
    p.finish_section();

    detail_::print_inputs(p, mod.inputs());
    p << "\n";
    detail_::print_results(p, mod.results());
    detail_::print_submods(p, mod.submods());

    p.finish_section();
    return ss.str();
}

} // namespace pluginplay::printing
