/*
** Copyright 2017-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.
*/

#include <stdio.h>
#include <bal_api.h>

#undef _SYS_QUEUE_H_

#include "asfvolt16_driver.h"
#include "bal_subscriber_terminal_hdlr.h"

/********************************************************************\
 * Function    : bal_subscriber_terminal_cfg_set                    *
 * Description : Configures the subscriber terminal(ONU)            *
 ********************************************************************/
uint32_t bal_subscriber_terminal_cfg_set(BalSubscriberTerminalCfg *onu_cfg)
{

    bcmos_errno err = BCM_ERR_OK;
    bcmbal_subscriber_terminal_cfg sub_term_obj = {};
    bcmbal_subscriber_terminal_key subs_terminal_key;
    bcmos_bool skip_onu = BCMOS_FALSE;

    int idx;

    subs_terminal_key.sub_term_id = onu_cfg->key->sub_term_id;
    subs_terminal_key.intf_id = onu_cfg->key->intf_id;

    ASFVOLT_LOG(ASFVOLT_INFO, "Bringing up the subscriber terminal: %d\n", onu_cfg->key->sub_term_id);

    /*
     * Set the key in the subscriber terminal object
     */
    BCMBAL_CFG_INIT(&sub_term_obj, subscriber_terminal, subs_terminal_key);

    {
       bcmbal_serial_number serial_num = {} ;
       bcmbal_serial_number zero_serial_num =  {};
       bcmbal_registration_id registration_id =  {};
       int has_serial_num = BCMOS_FALSE;
       int has_registration_id = BCMOS_FALSE;
       char two_digit_buf[3];

       two_digit_buf[2] = 0;

       ASFVOLT_LOG(ASFVOLT_DEBUG, "Before encoding,Vendor Id(%s),Vendor Specific Id(%s), Registration Id(%s)\n",
		       onu_cfg->data->serial_number->vendor_id, 
		       onu_cfg->data->serial_number->vendor_specific,
		       onu_cfg->data->registration_id);

       char vendor_id[20];
       memset(&vendor_id, 0, 20);
       sprintf(vendor_id,"%2X%2X%2X%2X",
		       onu_cfg->data->serial_number->vendor_id[0],
		       onu_cfg->data->serial_number->vendor_id[1],
		       onu_cfg->data->serial_number->vendor_id[2],
		       onu_cfg->data->serial_number->vendor_id[3]);
       onu_cfg->data->serial_number->vendor_id = vendor_id;
       ASFVOLT_LOG(ASFVOLT_DEBUG, "After encoding,Vendor Id(%s),Vendor Specific Id(%s), Registration Id(%s)\n",
		       onu_cfg->data->serial_number->vendor_id, 
		       onu_cfg->data->serial_number->vendor_specific,
		       onu_cfg->data->registration_id);

       /* Vendor Id is totally 16 byte string and should be
          send in hexadecimmal format */
       for(idx=0; idx<2*sizeof(serial_num.vendor_id); idx+=2)
       {
          memcpy(two_digit_buf, &onu_cfg->data->serial_number->vendor_id[idx], 2);
          serial_num.vendor_id[idx>>1] = strtol(two_digit_buf, NULL, 16);
          has_serial_num = BCMOS_TRUE;
       }
       for(idx=0; idx<2*sizeof(serial_num.vendor_specific); idx+=2)
       {
          memcpy(two_digit_buf, &onu_cfg->data->serial_number->vendor_specific[idx], 2);
          serial_num.vendor_specific[idx>>1] = strtol(two_digit_buf, NULL, 16);
       }

       ASFVOLT_CFG_PROP_SET(sub_term_obj, subscriber_terminal, serial_number,
                  has_serial_num, serial_num);

       /* Registration ID is a string and should be given in hexadecimal format */
       for(idx=0; idx<strlen(onu_cfg->data->registration_id) && idx<2*sizeof(registration_id.arr); idx+=2)
       {
          memcpy(two_digit_buf, &onu_cfg->data->registration_id[idx], 2);
          registration_id.arr[idx>>1] = strtol(two_digit_buf, NULL, 16);
          has_registration_id = BCMOS_TRUE;
       }

       ASFVOLT_CFG_PROP_SET(sub_term_obj, subscriber_terminal, registration_id,
                  has_registration_id, registration_id);

       if (!memcmp(&serial_num, &zero_serial_num, sizeof(serial_num)))
          skip_onu = BCMOS_TRUE;
    }

    ASFVOLT_CFG_PROP_SET(sub_term_obj, subscriber_terminal, admin_state,
                  BCMOS_TRUE, BCMBAL_STATE_UP);

    if (!skip_onu)
    {

       /*ASFVOLT_LOG(ASFVOLT_DEBUG, "Onu's(%d) Serial number %02x%02x%02x%2x%02x%02x%02x%02x\n", 
             onu_cfg->key->sub_term_id,
             sub_term_obj.data->serial_number.vendor_id[0], sub_term_obj.data->serial_number.vendor_id[1],
             sub_term_obj.data->serial_number.vendor_id[2], sub_term_obj.data->serial_number.vendor_id[3],
             sub_term_obj.data->serial_number.vendor_specific[0], sub_term_obj.data->serial_number.vendor_specific[1],
             sub_term_obj.data->serial_number.vendor_specific[2], sub_term_obj.data->serial_number.vendor_specific[3]);*/

       err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(sub_term_obj.hdr));

       ASFVOLT_LOG(ASFVOLT_DEBUG, 
                   "\n   ....SENT SUBSCRIBER TERMINAL %s UP %d on interface %d...\n",
                   (BCM_ERR_OK != err) ? "NOT" : "\b",
                   subs_terminal_key.sub_term_id,
                   subs_terminal_key.intf_id);
    }
    else
    {
       ASFVOLT_LOG(ASFVOLT_DEBUG, 
                   "Skipping activation of subscriber terminal %d on interface %d\n",
                   subs_terminal_key.sub_term_id,
                   subs_terminal_key.intf_id);
       err = BAL_ERRNO__BAL_ERR_PARM;
    }

    return BAL_ERRNO__BAL_ERR_OK;
}


/********************************************************************\
 * Function    : bal_subscriber_terminal_indication_cb              *
 * Description : Call Back indication registered with BAL to handle *
 *               events related to subscriber terminal(ONU)         *
 ********************************************************************/
bcmos_errno bal_subscriber_terminal_indication_cb(bcmbal_obj *obj)
{
    bcmos_errno result = BCM_ERR_OK;

#if 0
    bcmbal_subscriber_terminal_cfg *cfg = ((bcmbal_subscriber_terminal_cfg *)obj);

    if(BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL == obj->obj_type)
    {
       bcmbal_serial_number *p_serial_number =
                 (((bcmbal_subscriber_terminal_cfg *)obj)->data->serial_number);

       if(BCMBAL_SUB_ID_UNKNOWN == (((bcmbal_subscriber_terminal_cfg *)obj)->key.sub_term_id))
       {
          ASFVOLT_LOG(ASFVOLT_INFO, "New ONU Discovered. serial number "
                "%2X%2X%2X%2X%1X%1X%1X%1X%1X%1X%1X%1X "
                "on PON %d\n",
                p_serial_number->vendor_id[0],
                p_serial_number->vendor_id[1],
                p_serial_number->vendor_id[2],
                p_serial_number->vendor_id[3],
                p_serial_number->vendor_specific[0]>>4 & 0x0f,
                p_serial_number->vendor_specific[0] & 0x0f,
                p_serial_number->vendor_specific[1]>>4 & 0x0f,
                p_serial_number->vendor_specific[1] & 0x0f,
                p_serial_number->vendor_specific[2]>>4 & 0x0f,
                p_serial_number->vendor_specific[2] & 0x0f,
                p_serial_number->vendor_specific[3]>>4 & 0x0f,
                p_serial_number->vendor_specific[3] & 0x0f,

                ((bcmbal_subscriber_terminal_cfg *)obj)->key.intf_id);

       }
       else
       {
          ASFVOLT_LOG(ASFVOLT_INFO, "Event on existing ONU. serial number "
                "%2X%2X%2X%2X%1X%1X%1X%1X%1X%1X%1X%1X "
                "on PON %d\n",
                p_serial_number->vendor_id[0],
                p_serial_number->vendor_id[1],
                p_serial_number->vendor_id[2],
                p_serial_number->vendor_id[3],
                p_serial_number->vendor_specific[0]>>4 & 0x0f,
                p_serial_number->vendor_specific[0] & 0x0f,
                p_serial_number->vendor_specific[1]>>4 & 0x0f,
                p_serial_number->vendor_specific[1] & 0x0f,
                p_serial_number->vendor_specific[2]>>4 & 0x0f,
                p_serial_number->vendor_specific[2] & 0x0f,
                p_serial_number->vendor_specific[3]>>4 & 0x0f,
                p_serial_number->vendor_specific[3] & 0x0f,

                ((bcmbal_subscriber_terminal_cfg *)obj)->key.intf_id);

       }
    }
    else
    {
       ASFVOLT_LOG(ASFVOLT_ERROR, 
                   "Invalid object type %d for subscriber terminal indication\n",
                   obj->obj_type);
 
    }

#endif
    return result;
}

/********************************************************************\
 * Function    : bal_subscriber_terminal_cfg_clear                  *
 * Description : clears the subscriber terminal(ONU) configuration  *
 ********************************************************************/
uint32_t bal_subscriber_terminal_cfg_clear(BalSubscriberTerminalKey *terminal_key)
{
    bcmos_errno err = BCM_ERR_OK;
    bcmbal_subscriber_terminal_cfg cfg;
    bcmbal_subscriber_terminal_key key = { };

    ASFVOLT_LOG(ASFVOLT_INFO, 
                    "Processing subscriber terminal cfg clear: %d\n",
                     terminal_key->sub_term_id);

    if (terminal_key->has_sub_term_id && 
                    terminal_key->has_intf_id)
    {
        key.sub_term_id = terminal_key->sub_term_id ;
        key.intf_id = terminal_key->intf_id ;
    }
    else
    {
       ASFVOLT_LOG(ASFVOLT_ERROR, 
                   "Invalid Key to handle subscriber terminal clear Req.subscriber_terminal_id(%d), Interface ID(%d)\n",
                   key.sub_term_id, key.intf_id);
 
        return BAL_ERRNO__BAL_ERR_PARM;
    }

    err = bcmbal_cfg_clear(DEFAULT_ATERM_ID, &cfg.hdr);
    err = BAL_ERRNO__BAL_ERR_OK;
    return err;
} 

/********************************************************************\
 * Function    : bal_subscriber_terminal_cfg_get                    *
 * Description : Get the subscriber terminal(ONU) configuration     *
 ********************************************************************/
uint32_t bal_subscriber_terminal_cfg_get(BalSubscriberTerminalKey *terminal_key, 
                                         BalSubscriberTerminalCfg *onu_cfg)
{

    bcmos_errno err = BCM_ERR_OK;
    bcmbal_subscriber_terminal_cfg cfg;         /**< declare main API struct */
    bcmbal_subscriber_terminal_key key = { };   /**< declare key */
    uint8_t *list_mem;  /**< declare memory buffer for variable-sized lists */

    ASFVOLT_LOG(ASFVOLT_INFO, 
                    "Processing subscriber terminal cfg get: %d\n",
                     onu_cfg->key->sub_term_id);

    if (terminal_key->has_sub_term_id && 
                    terminal_key->has_intf_id)
    {
        key.sub_term_id = terminal_key->sub_term_id ;
        key.intf_id = terminal_key->intf_id ;
    }
    else
    {
       ASFVOLT_LOG(ASFVOLT_ERROR, 
                   "Invalid Key to handle subscriber terminal Cfg Get subscriber_terminal_id(%d), Interface ID(%d)\n",
                   key.sub_term_id, key.intf_id);
 
        return BAL_ERRNO__BAL_ERR_PARM;
    }

    /* init the API struct */
    BCMBAL_CFG_INIT(&cfg, subscriber_terminal, key);

    BCMBAL_CFG_PROP_GET(&cfg, subscriber_terminal, all_properties);

    /* set memory to use for variable-sized lists */
    list_mem = malloc(BAL_DYNAMIC_LIST_BUFFER_SIZE);
    if (list_mem == NULL)
    {

       ASFVOLT_LOG(ASFVOLT_ERROR, 
                   "Memory allocation failed while handling subscriber terminal cfg get subscriber_terminal_id(%d), Interface ID(%d)\n",
                   key.sub_term_id, key.intf_id);
        return BAL_ERRNO__BAL_ERR_NOMEM;
    }

    memset(list_mem, 0, BAL_DYNAMIC_LIST_BUFFER_SIZE);
    BCMBAL_CFG_LIST_BUF_SET(&cfg, subscriber_terminal, list_mem, BAL_DYNAMIC_LIST_BUFFER_SIZE);

    /* call API */
    err = bcmbal_cfg_get(DEFAULT_ATERM_ID, &cfg.hdr);
    if (err != BCM_ERR_OK)
    {
       ASFVOLT_LOG(ASFVOLT_ERROR, 
                   "Failed to get information from BAL subscriber_terminal_id(%d), Interface ID(%d)\n",
                   key.sub_term_id, key.intf_id);
        return BAL_ERRNO__BAL_ERR_INTERNAL;
    }

    ASFVOLT_LOG(ASFVOLT_INFO, 
                  "To-Do. Send subscriber terminal details to Adapter\n");
    return BAL_ERRNO__BAL_ERR_OK;
}
