/**
 * @file FlowControlProtocol.h
 * FlowControlProtocol 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.
 */
#ifndef LIBMINIFI_INCLUDE_FLOWCONTROLPROTOCOL_H_
#define LIBMINIFI_INCLUDE_FLOWCONTROLPROTOCOL_H_

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>

#include <chrono>
#include <cinttypes>
#include <memory>
#include <string>
#include <thread>
#include <vector>

#include "core/logging/LoggerConfiguration.h"
#include "core/Property.h"
#include "properties/Configure.h"
#include "utils/file/FileUtils.h"

namespace org {
namespace apache {
namespace nifi {
namespace minifi {
class FlowController;

#define DEFAULT_NIFI_SERVER_PORT 9000
#define DEFAULT_REPORT_INTERVAL 1000  // 1 sec
#define MAX_READ_TIMEOUT 30000  // 30 seconds

// FlowControl Protocol Msg Type
typedef enum {
  REGISTER_REQ,  // Device Register Request from device to server which contain device serial number, current running flow YAML version
  REGISTER_RESP,  // Device Register Respond from server to device, may contain new flow.YAML from server ask device to apply and also device report interval
  REPORT_REQ,  // Period Device Report from device to server which contain device serial number, current running flow YAML name/version and other period report info
  REPORT_RESP,  // Report Respond from server to device, may ask device to update flow YAML or processor property
  MAX_FLOW_CONTROL_MSG_TYPE
} FlowControlMsgType;

// FlowControl Protocol Msg Type String
static const char *FlowControlMsgTypeStr[MAX_FLOW_CONTROL_MSG_TYPE] = { "REGISTER_REQ", "REGISTER_RESP", "REPORT_REQ", "REPORT_RESP" };

// Flow Control Msg Type to String
inline const char *FlowControlMsgTypeToStr(FlowControlMsgType type) {
  if (type < MAX_FLOW_CONTROL_MSG_TYPE)
    return FlowControlMsgTypeStr[type];
  else
    return nullptr;
}

// FlowControll Protocol Msg ID (Some Messages are fix length, Some are variable length (TLV)
typedef enum {
  // Fix length 8 bytes: client to server in register request, required field
  FLOW_SERIAL_NUMBER,
  // Flow YAML name TLV: client to server in register request and report request, required field
  FLOW_YML_NAME,
  // Flow YAML content, TLV: server to client in register respond, option field in case server want to ask client to load YAML from server
  FLOW_YML_CONTENT,
  // Fix length, 4 bytes Report interval in msec: server to client in register respond, option field
  REPORT_INTERVAL,
  // Processor Name TLV:  server to client in report respond, option field in case server want to ask client to update processor property
  PROCESSOR_NAME,
  // Processor Property Name TLV: server to client in report respond, option field in case server want to ask client to update processor property
  PROPERTY_NAME,
  // Processor Property Value TLV: server to client in report respond, option field in case server want to ask client to update processor property
  PROPERTY_VALUE,
  // Report Blob TLV: client to server in report request, option field in case client want to pickyback the report blob in report request to server
  REPORT_BLOB,
  MAX_FLOW_MSG_ID
} FlowControlMsgID;

// FlowControl Protocol Msg ID String
static const char *FlowControlMsgIDStr[MAX_FLOW_MSG_ID] = { "FLOW_SERIAL_NUMBER", "FLOW_YAML_NAME", "FLOW_YAML_CONTENT", "REPORT_INTERVAL", "PROCESSOR_NAME",
    "PROPERTY_NAME", "PROPERTY_VALUE", "REPORT_BLOB" };

#define TYPE_HDR_LEN 4  // Fix Hdr Type
#define TLV_HDR_LEN 8  // Type 4 bytes and Len 4 bytes

// FlowControl Protocol Msg Len
inline int FlowControlMsgIDEncodingLen(FlowControlMsgID id, int payLoadLen) {
  if (id == FLOW_SERIAL_NUMBER)
    return (TYPE_HDR_LEN + 8);
  else if (id == REPORT_INTERVAL)
    return (TYPE_HDR_LEN + 4);
  else if (id < MAX_FLOW_MSG_ID)
    return (TLV_HDR_LEN + payLoadLen);
  else
    return -1;
}

// Flow Control Msg Id to String
inline const char *FlowControlMsgIdToStr(FlowControlMsgID id) {
  if (id < MAX_FLOW_MSG_ID)
    return FlowControlMsgIDStr[id];
  else
    return nullptr;
}

// Flow Control Respond status code
typedef enum {
  RESP_SUCCESS,
  RESP_TRIGGER_REGISTER,  // Server respond to client report to re trigger register
  RESP_START_FLOW_CONTROLLER,  // Server respond to client to start flow controller
  RESP_STOP_FLOW_CONTROLLER,  // Server respond to client to stop flow controller
  RESP_FAILURE,
  MAX_RESP_CODE
} FlowControlRespCode;

// FlowControl Resp Code str
static const char *FlowControlRespCodeStr[MAX_RESP_CODE] = { "RESP_SUCCESS", "RESP_TRIGGER_REGISTER", "RESP_START_FLOW_CONTROLLER", "RESP_STOP_FLOW_CONTROLLER", "RESP_FAILURE" };

// Flow Control Resp Code to String
inline const char *FlowControlRespCodeToStr(FlowControlRespCode code) {
  if (code < MAX_RESP_CODE)
    return FlowControlRespCodeStr[code];
  else
    return nullptr;
}

// Common FlowControlProtocol Header
typedef struct {
  uint32_t msgType;  // Msg Type
  uint32_t seqNumber;  // Seq Number to match Req with Resp
  uint32_t status;  // Resp Code, see FlowControlRespCode
  uint32_t payloadLen;  // Msg Payload length
} FlowControlProtocolHeader;

// FlowControlProtocol Class
class FlowControlProtocol {
 public:
  // Constructor
  /*!
   * Create a new control protocol
   */
  FlowControlProtocol(FlowController *controller, const std::shared_ptr<Configure> &configure)
      : logger_(logging::LoggerFactory<FlowControlProtocol>::getLogger()) {
    _controller = controller;
    _socket = 0;
    _serverName = "localhost";
    _serverPort = DEFAULT_NIFI_SERVER_PORT;
    _registered = false;
    _seqNumber = 0;
    _reportInterval = DEFAULT_REPORT_INTERVAL;
    running_ = false;

    std::string value;

    if (configure->get(Configure::nifi_server_name, value)) {
      _serverName = value;
      logger_->log_info("NiFi Server Name %s", _serverName);
    }
    if (configure->get(Configure::nifi_server_port, value) && core::Property::StringToInt(value, _serverPort)) {
      logger_->log_info("NiFi Server Port: [%" PRIu16 "]", _serverPort);
    }
    if (configure->get(Configure::nifi_server_report_interval, value)) {
      core::TimeUnit unit;
      if (core::Property::StringToTime(value, _reportInterval, unit) && core::Property::ConvertTimeUnitToMS(_reportInterval, unit, _reportInterval)) {
        logger_->log_info("NiFi server report interval: [%" PRId64 "] ms", _reportInterval);
      }
    } else {
      _reportInterval = 0;
    }
  }

  FlowControlProtocol(const FlowControlProtocol&) = delete;
  FlowControlProtocol& operator=(FlowControlProtocol) = delete;

  // Destructor
  virtual ~FlowControlProtocol() {
    stop();
    if (_socket) utils::file::FileUtils::close(_socket);
  }

 public:
  // SendRegisterRequest and Process Register Respond, return 0 for success
  int sendRegisterReq();
  // SendReportReq and Process Report Respond, return 0 for success
  int sendReportReq();
  // Start the flow control protocol
  void start();
  // Stop the flow control protocol
  void stop();
  // Set Report BLOB for periodically report
  void setReportBlob(char *blob, int len) {
    std::lock_guard<std::mutex> lock(mutex_);
    _reportBlob.resize(len);
    memcpy(_reportBlob.data(), blob, len);
  }
  // Run function for the thread
  static void run(FlowControlProtocol *protocol);

 private:
  // Connect to the socket, return sock descriptor if success, 0 for failure
  int connectServer(const char *host, uint16_t port);
  // Send Data via the socket, return -1 for failure
  int sendData(uint8_t *buf, int buflen);
  // Read length into buf, return -1 for failure and 0 for EOF
  int readData(uint8_t *buf, int buflen);
  // Select on the socket
  int selectClient(int msec);
  // Read the header
  int readHdr(FlowControlProtocolHeader *hdr);
  // encode uint32_t
  uint8_t *encode(uint8_t *buf, uint32_t value) {
    *buf++ = (value & 0xFF000000) >> 24;
    *buf++ = (value & 0x00FF0000) >> 16;
    *buf++ = (value & 0x0000FF00) >> 8;
    *buf++ = (value & 0x000000FF);
    return buf;
  }

  // encode uint32_t
  uint8_t *decode(uint8_t *buf, uint32_t &value) {
    value = ((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]));
    return (buf + 4);
  }

  // encode byte array
  uint8_t *encode(uint8_t *buf, uint8_t *bufArray, int size) {
    memcpy(buf, bufArray, size);
    buf += size;
    return buf;
  }

  // encode std::string
  uint8_t *encode(uint8_t *buf, const std::string& value) {
    // add the \0 for size
    buf = encode(buf, value.size() + 1);
    buf = encode(buf, const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(value.c_str())), value.size() + 1);
    return buf;
  }

  std::mutex mutex_;
  std::shared_ptr<logging::Logger> logger_;
  // NiFi server Name
  std::string _serverName;
  // NiFi server port
  uint16_t _serverPort;
  uint8_t _serialNumber[8] = {0};
  int _socket;  // to server
  int64_t _reportInterval;  // in msec
  bool _registered;  // whether it was registered to the NiFi server
  uint32_t _seqNumber;
  FlowController *_controller = nullptr;
  std::vector<char> _reportBlob;
  std::thread _thread;
  bool running_;
};

}  // namespace minifi
}  // namespace nifi
}  // namespace apache
}  // namespace org
#endif  // LIBMINIFI_INCLUDE_FLOWCONTROLPROTOCOL_H_
