#include "cmm.h"
#include "itf.h"
#include "ffbridge.h"
#include "cmmd.h"
#include "fpp.h"
#include <sys/ioctl.h>
 
/* Structure representing a pppoe entry (internally to cmm) */
struct PPPoERelayEntry {
	struct PPPoERelayEntry *next;
	int count;
	fpp_pppoe_relay_cmd_t *pppoe;
};

struct PPPoERelayEntry *relay_table = NULL;
pthread_mutex_t RelayMutex = PTHREAD_MUTEX_INITIALIZER;

/************************************************************
*
*
*
*************************************************************/

#if 1

static int cmmGetIfMac(unsigned char *ifname, unsigned char *mac){
    struct ifreq ifr;
    int fd;

    memcpy(ifr.ifr_name,ifname,sizeof(ifr.ifr_name));
    fd = socket(AF_INET, SOCK_DGRAM,0);

    if ( fd < 0 )
    {
        cmm_print(DEBUG_ERROR, "%s::%d:Socket Creation Failed  \n",__func__, __LINE__);
        return -1;
    }

    if ( ioctl(fd, SIOCGIFHWADDR, &ifr) < 0 )
    {
        cmm_print(DEBUG_ERROR, "%s::%d:Ioctl Call Failed \n",__func__, __LINE__);
        close(fd);
        return -1;
    }
    memcpy(mac,ifr.ifr_hwaddr.sa_data,IFHWADDRLEN);
    close(fd);
    return 0;
}

static int cmmRelayAdd(FCI_CLIENT * fci_handler, struct fpp_relay_info *sh, u_int16_t *res_buf, u_int16_t *res_len)
{
    struct PPPoERelayEntry *temp, *new_relay_entry = NULL;
    fpp_pppoe_relay_cmd_t *cmd;
    int ret = 0;
    int in_ifindex = -1, out_ifindex = -1, phys_in_ifindex = -1, phys_out_ifindex = -1;
    char in_ifname[IFNAMSIZ], out_ifname[IFNAMSIZ];
    res_buf[0] = CMMD_ERR_NOT_CONFIGURED;
    *res_len = 2;

    __pthread_mutex_lock(&RelayMutex);
    __pthread_mutex_lock(&itf_table.lock);
    /*Check if we have not already been sent to Forward Engine */
    temp = relay_table;

    while (temp != NULL) {
        if (!memcmp(temp->pppoe->peermac1, sh->peermac1, 6)
            && temp->pppoe->sesID == sh->sesID
            && !memcmp(temp->pppoe->peermac2, sh->peermac2, 6)
            && temp->pppoe->relaysesID == sh->relaysesID) {
            cmm_print(DEBUG_INFO, "Relay Match found\n");
            break;
        }

        temp = temp->next;
    }

    if (temp) {
        temp->count++;
        goto end;
    }

  /* Check the interface names whether they are valid and get the physical interface
   * names for bridge interfaces */

    memset(in_ifname , 0, IFNAMSIZ);
    memset(out_ifname , 0, IFNAMSIZ);

    in_ifindex = if_nametoindex(sh->ipifname);
    if (!in_ifindex)
    {
        cmm_print(DEBUG_ERROR, "%s::%d:if_nametoindex Failed  %s\n",__func__, __LINE__, sh->ipifname);
        goto end;
    }

    if ( __itf_is_bridge(in_ifindex))
    {

        cmm_print(DEBUG_INFO, "%s::%d:IP interface name is Bridge interface : %d\n",__func__, __LINE__, in_ifindex);
        phys_in_ifindex = cmmBrGetPhysItf(in_ifindex, sh->peermac1);
        if (phys_in_ifindex < 0)
        {
        	cmm_print(DEBUG_ERROR, "%s::%d:Error in finding the Physical interface  %d\n",__func__, __LINE__, phys_in_ifindex);
                goto end;
        }

        cmm_print(DEBUG_INFO, "%s::%d:Physical interface is : %d\n",__func__, __LINE__, phys_in_ifindex);
        if (! __itf_is_programmed(phys_in_ifindex))
        {
		cmm_print(DEBUG_ERROR, "%s::%d:Interface is not programmed to FPP  %d\n",__func__, __LINE__, phys_in_ifindex);
        	goto end;
        }

        if_indextoname(phys_in_ifindex, in_ifname);
    }
    else
    {
        if (! __itf_is_programmed(in_ifindex))
        {
		cmm_print(DEBUG_ERROR, "%s::%d:Interface is not programmed to FPP  %d\n",__func__, __LINE__, in_ifindex);
        	goto end;
        }
    	memcpy(in_ifname,sh->ipifname, 6);
    }

    out_ifindex = if_nametoindex(sh->opifname);
    if (!out_ifindex)
    {
        cmm_print(DEBUG_ERROR, "%s::%d:if_nametoindex Failed  %s\n",__func__, __LINE__, sh->opifname);
        goto end;
    }

    if (  __itf_is_bridge(out_ifindex))
    {
        phys_out_ifindex = cmmBrGetPhysItf(out_ifindex, sh->peermac2);
        if (phys_out_ifindex < 0)
        {
        	cmm_print(DEBUG_ERROR, "%s::%d:Error in finding the Physical interface  %d\n",__func__, __LINE__, phys_out_ifindex);
                goto end;
        }
        cmm_print(DEBUG_INFO, "%s::%d:Physical interface is : %d\n",__func__, __LINE__, phys_out_ifindex);
        if (! __itf_is_programmed(phys_out_ifindex))
        {
		cmm_print(DEBUG_ERROR, "%s::%d:Interface is not programmed to FPP  %d\n",__func__, __LINE__, phys_out_ifindex);
        	goto end;
        }
        if_indextoname(phys_out_ifindex, out_ifname);
    }
    else
    {
        if (! __itf_is_programmed(out_ifindex))
        {
		cmm_print(DEBUG_ERROR, "%s::%d:Interface is not programmed to FPP  %d\n",__func__, __LINE__, out_ifindex);
        	goto end;
        }
     	memcpy(out_ifname,sh->opifname, 6);
    }

    /*No existing entry found, try to create a new one */
    cmd = (fpp_pppoe_relay_cmd_t *) malloc(sizeof(fpp_pppoe_relay_cmd_t));
    if (cmd == NULL)
    {
        cmm_print(DEBUG_ERROR, "%s::%d:Error while allocating memory for PPPoERelayCommand \n",__func__, __LINE__);
        ret = -1;
        goto end;
    }

    new_relay_entry =  (struct PPPoERelayEntry *) malloc(sizeof(struct PPPoERelayEntry));
    if (new_relay_entry == NULL)
    {
        cmm_print(DEBUG_ERROR, "%s::%d:Error while allocating memory for PPPoERelayEntry \n",__func__, __LINE__);
        ret = -1;
        free(cmd);
        goto end;
    }
    
    
    /* Getting the input/output interface MAC address from the kernel and copy to cmd structure*/
    if ( cmmGetIfMac((unsigned char *)sh->ipifname,(unsigned char *)cmd->ipif_mac) < 0 )
    {
	cmm_print(DEBUG_ERROR, "%s::%d:Error while getting the input interface mac \n",__func__, __LINE__);
	goto end;
    }
    if ( cmmGetIfMac((unsigned char *)sh->opifname,(unsigned char *)cmd->opif_mac) < 0 )
    {
	cmm_print(DEBUG_ERROR, "%s::%d:Error while getting the output interface mac \n",__func__, __LINE__);
	goto end;
    }

    cmm_print(DEBUG_INFO, "Send CMD_PPPOE_RELAY_ENTRY ACTION_REGISTER\n");
    cmd->action = FPP_ACTION_REGISTER;
    cmd->sesID = sh->sesID;
    memcpy(cmd->peermac1, sh->peermac1, 6);
    memcpy(cmd->ipifname, in_ifname, IFNAMSIZ);
    cmd->relaysesID = sh->relaysesID;
    memcpy(cmd->peermac2, sh->peermac2, 6);
    memcpy(cmd->opifname, out_ifname, IFNAMSIZ);
#if 1
    cmm_print(DEBUG_INFO,
              "Sending command %02x:%02x:%02x:%02x:%02x:%02x(%s %d) to %02x:%02x:%02x:%02x:%02x:%02x(%s %d)\n",
              cmd->peermac1[0], cmd->peermac1[1], cmd->peermac1[2],
              cmd->peermac1[3], cmd->peermac1[4], cmd->peermac1[5],
              cmd->ipifname, cmd->sesID, cmd->peermac2[0],
              cmd->peermac2[1], cmd->peermac2[2], cmd->peermac2[3],
              cmd->peermac2[4], cmd->peermac2[5], cmd->opifname,
              cmd->relaysesID);
#endif
    ret = fci_cmd(fci_handler, FPP_CMD_PPPOE_RELAY_ENTRY, (unsigned short *) cmd, sizeof(*cmd), res_buf, res_len);
    if (ret != 0 || res_buf[0] != FPP_ERR_OK)
    {
         if (ret != 0) 
             cmm_print(DEBUG_ERROR, "Error '%s' when sending CMD_PPPOE_RELAY_ENTRY, ACTION_REGISTER\n", strerror(errno));
         else
             cmm_print(DEBUG_ERROR, "Error %d when sending CMD_PPPOE_RELAY_ENTRY, ACTION_REGISTER\n", res_buf[0]);
         free(cmd);
         free(new_relay_entry);
         goto end;
    }


    cmm_print(DEBUG_INFO, "Send CMD_PPPOE_RELAY_ENTRY SUCCESS\n");
    new_relay_entry->count = 1;
    new_relay_entry->pppoe = cmd;

    new_relay_entry->next = relay_table;
    relay_table = new_relay_entry;


  end:
    __pthread_mutex_unlock(&itf_table.lock);
    __pthread_mutex_unlock(&RelayMutex);
    return ret;
}
#endif
static int cmmRelayRemove(FCI_CLIENT * fci_handler,fpp_relay_info_t *sh, u_int16_t *res_buf, u_int16_t *res_len);

int cmmRelayProcessClientCmd(FCI_CLIENT * fci_handle, int function_code,
                             u_int8_t *cmd_buf, u_int16_t cmd_len, u_int16_t *res_buf, u_int16_t *res_len)
{
    cmmd_relay_info_t *sh;
    int rc = 0;

    sh = (cmmd_relay_info_t *) cmd_buf;
    switch (function_code) {
    case CMMD_CMD_PPPOE_RELAY_ADD:
#if 0
        cmm_print(DEBUG_INFO,
                  "Received CMD_PPPOE_RELAY_ENTRY command from RP-PPPoE...\n");
        cmm_print(DEBUG_INFO, "size:%d\n", buffer_size);
        cmm_print(DEBUG_INFO,
                  "Received the peers %02x:%02x:%02x:%02x:%02x:%02x(%s %d) to %02x:%02x:%02x:%02x:%02x:%02x(%s %d)\n",
                  sh->peermac1[0], sh->peermac1[1], sh->peermac1[2],
                  sh->peermac1[3], sh->peermac1[4], sh->peermac1[5],
                  sh->ipifname, sh->sesID, sh->peermac2[0],
                  sh->peermac2[1], sh->peermac2[2], sh->peermac2[3],
                  sh->peermac2[4], sh->peermac2[5], sh->opifname,
                  sh->relaysesID);
#endif
        rc = cmmRelayAdd(fci_handle, sh, res_buf, res_len);
        break;

    case CMMD_CMD_PPPOE_RELAY_REMOVE:
        rc = cmmRelayRemove(fci_handle, sh, res_buf, res_len);
        break;

    default:
        res_buf[0] = CMMD_ERR_UNKNOWN_COMMAND;
        *res_len = 2;
        break;

    }
    return rc;
}

/*****************************************************************
 * * cmmPPPoELocalShow
 * *
 * *
 * ******************************************************************/
int cmmRelayLocalShow(struct cli_def *cli, char *command, char *argv[],
                      int argc)
{
    struct PPPoERelayEntry *temp;

    __pthread_mutex_lock(&RelayMutex);

    for (temp = relay_table; temp != NULL; temp = temp->next) {
        if (temp->pppoe) {
            cli_print(cli, "%02x.%02x.%02x.%02x.%02x.%02x[%s  %d]<==::==>%02x.%02x.%02x.%02x.%02x.%02x[%s  %d]",
                      temp->pppoe->peermac1[0],temp->pppoe->peermac1[1],
                      temp->pppoe->peermac1[2],temp->pppoe->peermac1[3],
                      temp->pppoe->peermac1[4],temp->pppoe->peermac1[5],
            	      temp->pppoe->ipifname,temp->pppoe->sesID,
                      temp->pppoe->peermac2[0],temp->pppoe->peermac2[1],
                      temp->pppoe->peermac2[2],temp->pppoe->peermac2[3],
                      temp->pppoe->peermac2[4],temp->pppoe->peermac2[5],
		      temp->pppoe->opifname,temp->pppoe->relaysesID);
        } else
            cli_print(cli, "Internal Error");
    }

    __pthread_mutex_unlock(&RelayMutex);

    return CLI_OK;
}


/*****************************************************************
 * * cmmRelayRemove
 * *
 * *
 * ******************************************************************/
static int cmmRelayRemove(FCI_CLIENT * fci_handler,fpp_relay_info_t *sh, u_int16_t *res_buf, u_int16_t *res_len)
{
    struct PPPoERelayEntry *temp = NULL, *prevEntry = NULL;
    fpp_pppoe_relay_cmd_t *cmd;
    int ret = 0;
    res_buf[0] = CMMD_ERR_NOT_CONFIGURED;
    *res_len = 2;

    __pthread_mutex_lock(&RelayMutex);

    temp = relay_table;
    if (temp == NULL) {
        cmm_print(DEBUG_ERROR, "relay_table is NULL\n");
        goto end;
    }
    // Do a test on the first of the list
    while ((temp != NULL)) {
        if (!memcmp(temp->pppoe->peermac1, sh->peermac1, 6)
            && temp->pppoe->sesID == sh->sesID
            &&!memcmp(temp->pppoe->peermac2, sh->peermac2, 6)
            && temp->pppoe->relaysesID == sh->relaysesID) {
            cmm_print(DEBUG_ERROR, "An entry has been found to remove\n");
            break;
        } else {
            prevEntry = temp;
            temp = temp->next;
        }
    }
    // The entry have not been found, should not happen
    if (temp == NULL) {
        cmm_print(DEBUG_ERROR,
                  "An entry have been removed already on localtable or the delete command for same entry\n");
        goto end;
    }


    cmd = temp->pppoe;
    cmd->action = FPP_ACTION_DEREGISTER;

#if 1
    cmm_print(DEBUG_INFO,
              "Removing Entry %02x:%02x:%02x:%02x:%02x:%02x(%s %d) to %02x:%02x:%02x:%02x:%02x:%02x(%s %d)\n",
              cmd->peermac1[0], cmd->peermac1[1], cmd->peermac1[2],
              cmd->peermac1[3], cmd->peermac1[4], cmd->peermac1[5],
              cmd->ipifname, cmd->sesID, cmd->peermac2[0],
              cmd->peermac2[1], cmd->peermac2[2], cmd->peermac2[3],
              cmd->peermac2[4], cmd->peermac2[5], cmd->opifname,
              cmd->relaysesID);
#endif

    ret = fci_cmd(fci_handler, FPP_CMD_PPPOE_RELAY_ENTRY, (unsigned short *) cmd, sizeof(fpp_pppoe_relay_cmd_t), res_buf, res_len);
    if (ret != 0 || (res_buf[0] != FPP_ERR_OK && res_buf[0] != FPP_ERR_PPPOE_ENTRY_NOT_FOUND))	
    {
        if (ret != 0)
            cmm_print(DEBUG_ERROR, "Error '%s' while sending CMD_PPPOE_RELAY_ENTRY, ACTION_DEREGISTER\n", strerror(errno));
        else
            cmm_print(DEBUG_ERROR, "Error %d while sending CMD_PPPOE_RELAY_ENTRY, ACTION_DEREGISTER\n", res_buf[0]);
        goto end;
    }

    if (prevEntry == NULL)
        relay_table = temp->next;
    else
        prevEntry->next = temp->next;

    free(temp->pppoe);
    free(temp);
  end:
    __pthread_mutex_unlock(&RelayMutex);
    return ret;
}

static int relay_print_usage()
{
	cmm_print(DEBUG_ERROR,
		 "Usage: relay <add|del> <MAC1> <MAC2> <IN iface> <OUT iface> <session ID> <relay session ID>\n"
		 "\n"
		 "\n"
		 "       Ex:  relay add 00:00:00:00:00:01 00:00:00:00:00:02 eth2 eth1 1 1\n"
		 "            relay del 00:00:00:00:00:01 00:00:00:00:00:02 eth2 eth1 1 1\n"
		);
	return -1;
}

static int relay_parse_cmd(int argc, char ** keywords, daemon_handle_t daemon_handle)
{
	cmmd_relay_info_t cmd;
	char res_buf[CMM_BUF_SIZE];
	int fc;
	int rc;
	unsigned long tmp;

	if (argc < 7)
		return relay_print_usage();

	if (strcmp(*keywords, "add") == 0)
		fc = CMMD_CMD_PPPOE_RELAY_ADD;
	else if (strcmp(*keywords, "del") == 0)
		fc = CMMD_CMD_PPPOE_RELAY_REMOVE;
	else
		return relay_print_usage();

	keywords++;
	if (!parse_macaddr(*keywords, cmd.peermac1))
		return relay_print_usage();

	keywords++;
	if (!parse_macaddr(*keywords, cmd.peermac2))
		return relay_print_usage();
	
	keywords++;
	strncpy(cmd.ipifname, *keywords, sizeof(cmd.ipifname));

	keywords++;
	strncpy(cmd.opifname, *keywords, sizeof(cmd.opifname));

	keywords++;
	tmp = strtoul(*keywords, NULL, 0);
	if(tmp > UINT_MAX)
		return relay_print_usage();
	cmd.sesID = tmp;

	keywords++;
	tmp = strtoul(*keywords, NULL, 0);
	if(tmp > UINT_MAX)
		return relay_print_usage();
	cmd.relaysesID = tmp;

	rc = cmmSendToDaemon(daemon_handle, fc, &cmd, sizeof(cmd), res_buf);
	if (rc != 2) /* we expect 2 bytes in response */
	{
		cmm_print(DEBUG_STDERR, "unexpected response length %d\n", rc);
		return -1;
	}
	else if ((((u_int16_t*)res_buf)[0]) != CMMD_ERR_OK)
	{
		cmm_print(DEBUG_STDERR, "Error %d received from CMM Deamon\n", ((u_int16_t*)res_buf)[0]);
		return -1;
	}

	return 0;
}

int cmmRelayParseCmd(int argc, char ** keywords, int tabStart, daemon_handle_t daemon_handle)
{
        if (tabStart < argc)
                return relay_parse_cmd(argc - tabStart, &keywords[tabStart], daemon_handle);
        else
                return relay_print_usage();
}

