/**
 * @file GenerateFlowFile.h
 * GenerateFlowFile class declaration
 *
 * 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 "KamikazeProcessor.h"
#include "Exception.h"

namespace org {
namespace apache {
namespace nifi {
namespace minifi {
namespace processors {

const std::string KamikazeProcessor::OnScheduleExceptionStr = "This processor was configured to throw exception during onSchedule";
const std::string KamikazeProcessor::OnTriggerExceptionStr = "This processor was configured to throw exception during onTrigger";
const std::string KamikazeProcessor::OnScheduleLogStr = "KamikazeProcessor::onSchedule executed";
const std::string KamikazeProcessor::OnTriggerLogStr = "KamikazeProcessor::onTrigger executed";
const std::string KamikazeProcessor::OnUnScheduleLogStr = "KamikazeProcessor::onUnSchedule";

core::Property KamikazeProcessor::ThrowInOnSchedule(
    core::PropertyBuilder::createProperty("Throw in onSchedule")
    ->withDescription("Set to throw expcetion during onSchedule call")
    ->isRequired(true)
    ->withDefaultValue<bool>(false)->build());

core::Property KamikazeProcessor::ThrowInOnTrigger(
    core::PropertyBuilder::createProperty("Throw in onTrigger")
    ->withDescription("Set to throw expcetion during onTrigger call")
    ->isRequired(true)
    ->withDefaultValue<bool>(false)->build());

void KamikazeProcessor::initialize() {
  setSupportedProperties({ThrowInOnSchedule, ThrowInOnTrigger});
}

void KamikazeProcessor::onSchedule(core::ProcessContext *context, core::ProcessSessionFactory *sessionFactory) {
  std::string value;
  bool bool_value;

  _throwInOnTrigger = false;
  context->getProperty(ThrowInOnTrigger.getName(), value);
  _throwInOnTrigger = utils::StringUtils::StringToBool(value, bool_value) && bool_value;

  context->getProperty(ThrowInOnSchedule.getName(), value);
  if (utils::StringUtils::StringToBool(value, bool_value) && bool_value) {
    throw Exception(PROCESS_SCHEDULE_EXCEPTION, OnScheduleExceptionStr);
  }
  logger_->log_error("%s", OnScheduleLogStr);
}

void KamikazeProcessor::onTrigger(core::ProcessContext *, core::ProcessSession *) {
  if (_throwInOnTrigger) {
    throw Exception(PROCESSOR_EXCEPTION, OnTriggerExceptionStr);
  }
  logger_->log_error("%s", OnTriggerLogStr);
}

void KamikazeProcessor::onUnSchedule() {
  logger_->log_error("%s", OnUnScheduleLogStr);
}

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