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

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_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_status(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 gemport_id);
Status remove_gem_port(int32_t intf_id, int32_t gemport_id);
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);
#endif // OPENOLT_CORE_UTILS_H_
