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

#include "AgentDocs.h"
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <fstream>
#include <set>
#include <memory>
#include <string>
#include "core/ClassLoader.h"
#include "core/ConfigurableComponent.h"
#include "core/Core.h"
#include "core/Processor.h"
#include "core/Property.h"
#include "core/PropertyValidation.h"
#include "core/Relationship.h"
#include "io/validation.h"
#include "utils/file/FileUtils.h"
#include "agent/build_description.h"
#include "agent/agent_version.h"

namespace org {
namespace apache {
namespace nifi {
namespace minifi {
namespace docs {

std::string AgentDocs::extractClassName(const std::string &processor) const {
  auto lastOfIdx = processor.find_last_of(".");
  if (lastOfIdx != std::string::npos) {
    lastOfIdx++;  // if a value is found, increment to move beyond the .
    int nameLength = processor.length() - lastOfIdx;
    std::string processorName = processor.substr(lastOfIdx, nameLength);
    return processorName;
  }
  return processor;

}

void AgentDocs::generate(const std::string &docsdir, std::ostream &genStream) {
  std::map<std::string, ClassDescription> processorSet;
  for (const auto &group : minifi::AgentBuild::getExtensions()) {

    struct Components descriptions = BuildDescription::getClassDescriptions(group);
    for (const auto &processorName : descriptions.processors_) {
      processorSet.insert(std::make_pair(extractClassName(processorName.class_name_), processorName));
    }
  }
  for (const auto &processor : processorSet) {
    const std::string &filename = docsdir + utils::file::FileUtils::get_separator() + processor.first;
    std::ofstream outfile(filename);

    std::string description;

    bool foundDescription = minifi::AgentDocs::getDescription(processor.first, description);

    if (!foundDescription) {
      foundDescription = minifi::AgentDocs::getDescription(processor.second.class_name_, description);
    }

    outfile << "## " << processor.first << std::endl << std::endl;
    if (foundDescription) {
      outfile << "### Description " << std::endl << std::endl;
      outfile << description << std::endl;
    }

    outfile << "### Properties " << std::endl << std::endl;
    outfile
        << "In the list below, the names of required properties appear in bold. Any other properties (not in bold) are considered optional. The table also indicates any default values, and whether a property supports the NiFi Expression Language."
        << std::endl<< std::endl;

    outfile << "| Name | Default Value | Allowable Values | Description | " << std::endl << "| - | - | - | - | " << std::endl;
    for (const auto &prop : processor.second.class_properties_) {
      bool supportsEl = prop.second.supportsExpressionLangauge();
      outfile << "|";
      if (prop.second.getRequired()) {
        outfile << "**";
      }
      outfile << prop.first;
      if (prop.second.getRequired()) {
        outfile << "**";
      }
      const auto allowableValues = prop.second.getAllowedValues();
      std::stringstream s;
      std::copy(allowableValues.begin(),allowableValues.end(), std::ostream_iterator<std::string>(s,"<br>"));
      outfile << "|";
      const auto defaultValue = prop.second.getDefaultValue().to_string();
      if (defaultValue.size() == 1 && (int)defaultValue.c_str()[0] == 0x0a){
        outfile << "\\n";
      }
      else{
        outfile << defaultValue;
      }
      outfile << "|" << s.str() << "|" << prop.second.getDescription();
      if (supportsEl){
        outfile << "<br/>**Supports Expression Language: true**";
      }
      outfile << "|" << std::endl;
    }
    outfile << "### Properties " << std::endl << std::endl;
    outfile << "| Name | Description |" << std::endl << "| - | - |" << std::endl;
    for (const auto &rel : processor.second.class_relationships_) {
      outfile << "|" << rel.getName() << "|" << rel.getDescription() << "|" << std::endl;
    }

    outfile << std::endl;

  }

  std::map<std::string,std::string> fileList;

  auto fileFind = [&fileList,this](const std::string& base_path, const std::string& file) -> bool {
    if (file.find(".extra") == std::string::npos)
      fileList.insert(std::make_pair(file, base_path + utils::file::FileUtils::get_separator() + file));
    return true;
  };

  // shortened with list_dir
  utils::file::FileUtils::list_dir(docsdir, fileFind, logging::LoggerFactory<AgentDocs>::getLogger());
  genStream << "<!--"
  "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."
  "-->"<<std::endl;
  genStream << "# Processors" << std::endl << std::endl;
  genStream << "## Table of Contents" << std::endl << std::endl;

  for(const auto &file : fileList){
    std::string lcfile=file.first;
    std::transform(lcfile.begin(), lcfile.end(), lcfile.begin(), ::tolower);
    genStream << "- [" << file.first << "](#" << lcfile << ")" << std::endl;
  }

  for(const auto &file : fileList){
      std::ifstream filestream(file.second);
      genStream << filestream.rdbuf() << std::endl;
      std::ifstream filestreamExtra(file.second + ".extra");
      if (filestreamExtra.good()){
        genStream << filestreamExtra.rdbuf()<< std::endl;
      }
  }
}

} /* namespace docs */
} /* namespace minifi */
} /* namespace nifi */
} /* namespace apache */
} /* namespace org */
