/*
 * Copyright 2018-present Open Networking Foundation

 * Licensed 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 OPENOLT_CORE_UTILS_H_
#define OPENOLT_CORE_UTILS_H_
#include <string>
#include <unistd.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>

#include "core.h"
#include "core_data.h"
#include "error_format.h"
#include <grpc/grpc_security_constants.h>

extern "C"
{
#include <bcmolt_api.h>
#include <bcmolt_host_api.h>
#include <bcmolt_api_model_supporting_enums.h>
#include <bcmolt_api_model_supporting_structs.h>

#include <bcmolt_api_conn_mgr.h>
//CLI header files
#include <bcmcli_session.h>
#include <bcmcli.h>
#include <bcm_api_cli.h>

#include <bcmos_common.h>
#include <bcm_config.h>
// FIXME : dependency problem
// #include <bcm_common_gpon.h>
// #include <bcm_dev_log_task.h>
}


std::string serial_number_to_str(bcmolt_serial_number* serial_number);
std::string vendor_specific_to_str(const char* const serial_number);
uint16_t get_dev_id(void);
int get_default_tm_sched_id(int intf_id, std::string direction);
uint32_t get_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction, int tech_profile_id);
void free_tm_sched_id(int pon_intf_id, int onu_id, int uni_id, std::string direction, int tech_profile_id);
bool is_tm_sched_id_present(int pon_intf_id, int onu_id, int uni_id, std::string direction, int tech_profile_id);
bool check_tm_qmp_equality(std::vector<uint32_t> tmq_map_profileA, std::vector<uint32_t> tmq_map_profileB);
std::string* get_valid_queues_pbit_map(std::string *queues_pbit_map, uint32_t size);
std::vector<uint32_t> get_tmq_map_profile(std::string *queues_pbit_map, uint32_t *queues_priority_q, uint32_t size);
int get_tm_qmp_id(std::vector<uint32_t> tmq_map_profile);
void update_sched_qmp_id_map(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id,
                             uint32_t uni_id, int tm_qmp_id);
int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id);
int get_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id,
                  std::vector<uint32_t> tmq_map_profile);
bool free_tm_qmp_id(uint32_t sched_id,uint32_t pon_intf_id, uint32_t onu_id,
                    uint32_t uni_id, int tm_qmp_id);
int get_acl_id();
void free_acl_id (int acl_id);
uint16_t get_flow_id();
bool get_flow_ids(int num_of_flow_ids, uint16_t *flow_ids);
void free_flow_id (uint16_t flow_id);
void free_flow_ids(uint8_t num_flows, uint16_t *flow_ids);
std::string get_qos_type_as_string(bcmolt_egress_qos_type qos_type);
bcmolt_egress_qos_type get_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id, uint32_t queue_size=0);
void clear_qos_type(uint32_t pon_intf_id, uint32_t onu_id, uint32_t uni_id);
std::string GetDirection(int direction);
bcmos_errno wait_for_alloc_action(uint32_t intf_id, uint32_t alloc_id, AllocCfgAction action);
bcmos_errno wait_for_gem_action(uint32_t intf_id, uint32_t gem_port_id, GemCfgAction action);
bcmos_errno wait_for_onu_deactivate_complete(uint32_t intf_id, uint32_t onu_id);
char* openolt_read_sysinfo(const char* field_name, char* field_val);
Status pushOltOperInd(uint32_t intf_id, const char *type, const char *state);
void openolt_cli_get_prompt_cb(bcmcli_session *session, char *buf, uint32_t max_len);
int _bal_apiend_cli_thread_handler(long data);
bcmos_errno bcm_openolt_api_cli_init(bcmcli_entry *parent_dir, bcmcli_session *session);
bcmos_errno bcm_cli_quit(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms);
int get_status_bcm_cli_quit(void);
bcmos_errno bcmolt_apiend_cli_init();
bcmos_errno get_pon_interface_status(bcmolt_interface pon_ni, bcmolt_interface_state *state, bcmolt_status *los_status);
bcmos_errno get_onu_state(bcmolt_interface pon_ni, int onu_id, bcmolt_onu_state *onu_state);
bcmos_errno bcmolt_cfg_get_mult_retry(bcmolt_oltid olt, bcmolt_cfg *cfg);
unsigned NumNniIf_();
unsigned NumPonIf_();
bcmos_errno get_nni_interface_status(bcmolt_interface id, bcmolt_interface_state *state);
Status install_gem_port(int32_t intf_id, int32_t onu_id, int32_t uni_id, int32_t gemport_id, std::string board_technology);
Status remove_gem_port(int32_t intf_id, int32_t onu_id, int32_t uni_id, int32_t gemport_id, std::string board_technology);
Status enable_encryption_for_gem_port(int32_t intf_id, int32_t gemport_id, std::string board_technology);
Status update_acl_interface(int32_t intf_id, bcmolt_interface_type intf_type, uint32_t access_control_id,
                bcmolt_members_update_command acl_cmd);
Status install_acl(const acl_classifier_key acl_key);
Status remove_acl(int acl_id);
void formulate_acl_classifier_key(acl_classifier_key *key, const ::openolt::Classifier& classifier);
Status handle_acl_rule_install(int32_t onu_id, uint64_t flow_id, int32_t gemport_id,
                               const std::string flow_type, int32_t access_intf_id,
                               int32_t network_intf_id,
                               const ::openolt::Classifier& classifier);
void clear_gem_port(int gemport_id, int access_intf_id);
Status handle_acl_rule_cleanup(int16_t acl_id, int32_t intf_id, const std::string flow_type);
Status check_bal_ready();
Status check_connection();
std::string get_ip_address(const char* nw_intf);
bcmos_errno getOnuMaxLogicalDistance(uint32_t intf_id, uint32_t *mld);
char* get_intf_mac(const char* intf_name, char* mac_address, unsigned int max_size_of_mac_address);
void update_voltha_flow_to_cache(uint64_t voltha_flow_id, device_flow dev_flow);
void remove_voltha_flow_from_cache(uint64_t voltha_flow_id);
bool is_voltha_flow_installed(uint64_t voltha_flow_id );
const device_flow* get_device_flow(uint64_t voltha_flow_id);
const device_flow_params* get_device_flow_params(uint64_t voltha_flow_id);
trap_to_host_packet_type get_trap_to_host_packet_type(const ::openolt::Classifier& classifier);
bool is_packet_allowed(bcmolt_access_control_receive_eth_packet_data *data, int32_t gemport_id);
std::pair<grpc_ssl_client_certificate_request_type, bool> get_grpc_tls_option(const char* tls_option);
const std::string &get_grpc_tls_option();
bool is_grpc_secure();
std::pair<std::string, bool> read_from_txt_file(const std::string& file_name);
bool save_to_txt_file(const std::string& file_name, const std::string& content);
#endif // OPENOLT_CORE_UTILS_H_
