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