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

#ifndef EXTENSIONS_JNI_JVMCREATOR_H_
#define EXTENSIONS_JNI_JVMCREATOR_H_

#include <vector>
#include <string>
#include <memory>
#include "jvm/JVMLoader.h"
#include "jvm/JavaControllerService.h"
#include "utils/file/FileUtils.h"
#include "core/Core.h"
#include "core/logging/LoggerConfiguration.h"

namespace org {
namespace apache {
namespace nifi {
namespace minifi {
namespace jni {

/**
 * Can be used to load the JVM from NiFi properties.
 */
class JVMCreator : public minifi::core::CoreComponent {
 public:

  explicit JVMCreator(const std::string &name, utils::Identifier uuid = utils::Identifier())
      : minifi::core::CoreComponent(name, uuid),
        loader_(nullptr),
        logger_(logging::LoggerFactory<JVMCreator>::getLogger()) {
  }

  virtual ~JVMCreator();

  void configure(const std::vector<std::string> &jarFileListings) {
    std::vector<std::string> pathOrFiles;
    for (const auto &path : jarFileListings) {
      const auto vec = utils::StringUtils::split(path, ",");
      pathOrFiles.insert(pathOrFiles.end(), vec.begin(), vec.end());
    }

    for (const auto &path : pathOrFiles) {
      logger_->log_debug("Adding path %s", path);
      minifi::utils::file::FileUtils::addFilesMatchingExtension(logger_, path, ".jar", classpaths_);
    }

  }

  virtual void configure(const std::shared_ptr<Configure> &configuration) override {
    std::string pathListings, jvmOptionsStr;

    // assuming we have the options set and can access the JVMCreator

    if (configuration->get("nifi.framework.dir", pathListings)) {
      std::vector<std::string> paths;
      paths.emplace_back(pathListings);
      configure(paths);

      if (configuration->get("nifi.jvm.options", jvmOptionsStr)) {
        jvm_options_ = utils::StringUtils::split(jvmOptionsStr, ",");
      }

      initializeJVM();
    }
    std::string nar_dir, nar_dep, nar_docs;
    if (loader_ && configuration->get("nifi.nar.directory", nar_dir) && configuration->get("nifi.nar.deploy.directory", nar_dep)) {
      std::shared_ptr<jni::controllers::JavaControllerService> servicer = std::make_shared<jni::controllers::JavaControllerService>("BaseService");
      servicer->initialize();
      servicer->setProperty(jni::controllers::JavaControllerService::NarDirectory, nar_dir);
      servicer->setProperty(jni::controllers::JavaControllerService::NarDeploymentDirectory, nar_dep);
      servicer->setProperty(jni::controllers::JavaControllerService::NarDocumentDirectory, nar_docs);
      servicer->onEnable();
      loader_->setBaseServicer(servicer);
    }
  }

  void initializeJVM() {
    loader_ = minifi::jni::JVMLoader::getInstance(classpaths_, jvm_options_);
  }

 private:

  minifi::jni::JVMLoader *loader_;

  std::vector<std::string> jvm_options_;

  std::vector<std::string> classpaths_;

  std::shared_ptr<logging::Logger> logger_;
};

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

#endif /* EXTENSIONS_JNI_JVMCREATOR_H_ */
