/**
 *
 * 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 <regex.h>
#include <memory>
#include <algorithm>
#include <cctype>
#include <cstdint>
#include <cstring>
#include <iostream>
#include <iterator>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "utils/ByteArrayCallback.h"
#include "core/FlowFile.h"
#include "core/logging/Logger.h"
#include "core/ProcessContext.h"
#include "core/Relationship.h"
#include "GetEnvironmentalSensors.h"
#include "io/DataStream.h"
#include "io/StreamFactory.h"
#include "ResourceClaim.h"
#include "utils/StringUtils.h"

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

std::shared_ptr<utils::IdGenerator> GetEnvironmentalSensors::id_generator_ = utils::IdGenerator::getIdGenerator();

const char *GetEnvironmentalSensors::ProcessorName = "GetEnvironmentalSensors";

core::Relationship GetEnvironmentalSensors::Success("success", "All files are routed to success");

void GetEnvironmentalSensors::initialize() {
  logger_->log_trace("Initializing EnvironmentalSensors");
  // Set the supported properties
  std::set<core::Property> properties;

  setSupportedProperties(properties);
  // Set the supported relationships
  std::set<core::Relationship> relationships;
  relationships.insert(Success);
  setSupportedRelationships(relationships);
}

void GetEnvironmentalSensors::onSchedule(const std::shared_ptr<core::ProcessContext> &context, const std::shared_ptr<core::ProcessSessionFactory> &sessionFactory) {
  SensorBase::onSchedule(context, sessionFactory);

  humidity_sensor_ = RTHumidity::createHumidity(&settings);
  if (humidity_sensor_) {
    humidity_sensor_->humidityInit();
  } else {
    throw std::runtime_error("RTHumidity could not be initialized");
  }

  pressure_sensor_ = RTPressure::createPressure(&settings);
  if (pressure_sensor_) {
    pressure_sensor_->pressureInit();
  } else {
    throw std::runtime_error("RTPressure could not be initialized");
  }

}

void GetEnvironmentalSensors::notifyStop() {
  delete humidity_sensor_;
  delete pressure_sensor_;
}

GetEnvironmentalSensors::~GetEnvironmentalSensors() = default;

void GetEnvironmentalSensors::onTrigger(const std::shared_ptr<core::ProcessContext> &context, const std::shared_ptr<core::ProcessSession> &session) {

  auto flow_file_ = session->create();

  if (imu->IMURead()) {
    RTIMU_DATA imuData = imu->getIMUData();
    auto vector = imuData.accel;
    std::string degrees = RTMath::displayDegrees("acceleration", vector);
    flow_file_->addAttribute("ACCELERATION", degrees);
  } else {
    logger_->log_trace("IMURead returned false. Could not gather acceleration");
  }

  RTIMU_DATA data;

  bool have_sensor = false;

  if (humidity_sensor_->humidityRead(data)) {
    if (data.humidityValid) {
      have_sensor = true;
      std::stringstream ss;
      ss << std::fixed << std::setprecision(2) << data.humidity;
      flow_file_->addAttribute("HUMIDITY", ss.str());
    }
  } else {
    logger_->log_trace("Could not read humidity sensors");
  }

  if (pressure_sensor_->pressureRead(data)) {
    if (data.pressureValid) {
      have_sensor = true;
      {
        std::stringstream ss;
        ss << std::fixed << std::setprecision(2) << data.pressure;
        flow_file_->addAttribute("PRESSURE", ss.str());
      }

      if (data.temperatureValid) {
        std::stringstream ss;
        ss << std::fixed << std::setprecision(2) << data.temperature;
        flow_file_->addAttribute("TEMPERATURE", ss.str());
      }

    }
  } else {
    logger_->log_trace("Could not read pressure sensors");
  }

  if (have_sensor) {

    WriteCallback callback("GetEnvironmentalSensors");
    session->write(flow_file_, &callback);
    session->transfer(flow_file_, Success);
  }

}

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