/*
 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sstream>
#include <iostream>
#include <fstream>

#include "cmdiface.h"
#include "parser.h"
#include "debug.h"
#include "WlctPciAcss.h"
#include "pmc_file.h"
#include "udp_server.h"


struct open_interface_s *CmdIface::open_interfaces = NULL;
pthread_mutex_t CmdIface::open_interfaces_mutex = PTHREAD_MUTEX_INITIALIZER;
int CmdIface::interface_id = 0;

/*
*/
void *CmdIface::get_interface(const char *name)
{
    struct open_interface_s *s = open_interfaces;
    LOG_DEBUG << "Looking for interface: " << name << std::endl;

    while(s != NULL)
    {
        LOG_VERBOSE << "Checking interface for match: " << s->interface << std::endl;
        if(0 == strncasecmp(name, s->interface, MAX_INTERFACE_NAME))
        {
            LOG_VERBOSE << "Match found" << std::endl;
            return s->handler;
        }
        s = s->next;
    }

    return NULL;
}

/*
*/
void *CmdIface::add_interface(const char *name, void *handler)
{
    LOG_DEBUG << "Adding interface: " << name << std::endl;

    void *h = get_interface(name);
    if(h != NULL)
    {
        LOG_DEBUG << "The interface is already open" << std::endl;
        return h;			// Interface already opened
    }

    // Add interface to the list
    struct open_interface_s *s = new struct open_interface_s;
    if(s == NULL)
    {
        return NULL;
    }

    snprintf(s->interface, MAX_INTERFACE_NAME, "%s", name);
    s->handler = handler;
    pthread_mutex_lock(&open_interfaces_mutex);
    s->next = open_interfaces;
    open_interfaces = s;
    pthread_mutex_unlock(&open_interfaces_mutex);

    return handler;
}

/*
*/
void CmdIface::del_interface(void *handler)
{
    LOG_DEBUG << "Deleting interfaces by handler" << std::endl;

    struct open_interface_s *s = open_interfaces;
    struct open_interface_s *prev = NULL;

    while(s != NULL) {
        if(handler == s->handler)  {
            // Remove the interface from the list
            pthread_mutex_lock(&open_interfaces_mutex);
            if(prev != NULL)
                prev->next = s->next;
            else
                open_interfaces = s->next;
            pthread_mutex_unlock(&open_interfaces_mutex);
            delete s;
        }
        prev = s;
        s = s->next;
    }
}

/*
*/
int CmdIface::cmd_get_interfaces()
{
    INTERFACE_LIST interfaces;
    int num_interfaces;
    int rc;

    LOG_DEBUG << "Getting active WIGIG card interfaces" << std::endl;

    rc = GetInterfaces(&interfaces, &num_interfaces);
    LOG_DEBUG << "Found " << num_interfaces << " interfaces" << std::endl;

    std::ostringstream replyBuilder;

    if(rc == 0)
    {
        for(int i=0; i < num_interfaces; i++)
        {
            replyBuilder << interfaces.list[i].ifName << ' ';
        }
    }

    replyBuilder << "\r\n";
    m_Reply = replyBuilder.str();

    return 0;
}

/*
*/
int CmdIface::cmd_open_interface(char *interface)
{
    void *handler = NULL;
    int rc=0;

    LOG_DEBUG << "Opening an interface: " << interface << std::endl;

    if( strstr(interface, "SPARROW")|| strstr(interface, "sparrow")){
	rc = CreateDeviceAccessHandler(interface, MST_SPARROW, &handler);
    }
    else if(strstr(interface, "MARLON") || strstr(interface, "marlon")){
	rc = CreateDeviceAccessHandler(interface, MST_MARLON, &handler);
    }
    else{
        m_Reply = "0xDEAD\r\n";
    }
    if(rc != 0)
        m_Reply = "0xDEADDEAD\r\n";
    else {

        std::ostringstream replyBuilder;

        replyBuilder << interface << '_' << interface_id;
        add_interface(replyBuilder.str().c_str(), handler);
        replyBuilder << "\r\n";
        m_Reply = replyBuilder.str();
        interface_id++;                     // TODO: Should be protected by a mutex? I didn't see it's being used in the application
    }
    return 0;
}

/*
*/
int CmdIface::cmd_close_interface(char *interface)
{
    LOG_DEBUG << "Closing interface: " << interface << std::endl;

    void *handler = get_interface(interface);

    if(handler != NULL)
    {
        del_interface(handler);
        interface_id--;
    }
    else
    {
        LOG_WARNING << "Interface " << interface << " wasn't opened" << std::endl;
    }

    m_Reply = "0\r\n";
    return 0;
}

/*
*/
int CmdIface::cmd_r(char *interface, unsigned int address)
{
    unsigned int val = 0xDEADDEAD;
    void *handler = get_interface(interface);

    std::ostringstream replyBuilder;
    if(handler == NULL)
    {
        m_Reply = "0xDEADDEAD";
    }
    else
    {
        int rc = WlctAccssRead(handler, address, val);
        (void)rc;
        replyBuilder << val;
    }

    replyBuilder << "\r\n";
    m_Reply = replyBuilder.str();

    return 0;
}

/*
*/
int CmdIface::cmd_w(char *interface, unsigned int address, unsigned int data)
{
    int rc;
    void *handler = get_interface(interface);

    std::ostringstream replyBuilder;

    if(handler == NULL)
    {
        replyBuilder << "0xDEADDEAD";
    }
    else
    {
        rc = WlctAccssWrite(handler, address, data);
        if(rc == 0)
            replyBuilder << "0";
        else
            replyBuilder << "ERROR";
    }

    replyBuilder << "\r\n";
    m_Reply = replyBuilder.str();

    return 0;
}

/*
*/
int CmdIface::cmd_alloc_pmc(char *interface, unsigned int desc_size, unsigned int desc_num)
{
    int rc;
    LOG_DEBUG << "Allocating PMC descriptors:"
              << " interface = " << interface
              << " size = " << desc_size
              << " number = " << desc_num
              << std::endl;

    std::ostringstream replyBuilder;

    void *handler = get_interface(interface);
    if(handler == NULL)
    {
        LOG_DEBUG << "Cannot get handler for interface " << interface << std::endl;
        replyBuilder << "0xDEADDEAD";
    }
    else
    {
	rc = WlctAccssAllocPmc(handler, desc_size, desc_num);

	if(rc == 0)
        {
            LOG_DEBUG << "Successfully allocated PMC descriptors" << std::endl;
            replyBuilder << "0";
        }
        else
        {
            LOG_ERROR << "Error allocating PMC descriptors" << std::endl;
            replyBuilder << "ERROR";
        }
    }

    replyBuilder << "\r\n";
    m_Reply = replyBuilder.str();

    return 0;
}

/*
*/
int CmdIface::cmd_read_pmc(char *interface, unsigned int ref_number)
{
    LOG_DEBUG << "Reading PMC data:"
              << " interface = " << interface
              << " reference number = " << ref_number
              << std::endl;

    void *handler = get_interface(interface);

    if(handler == NULL)
    {
        LOG_ERROR << "No interface found: " << interface << std::endl;
        m_Reply = "0xDEADDEAD\r\n";
        return 0;
    }

    PmcFile pmcFile(ref_number);
    PmcFileWriter pmcFileWriter(pmcFile);
    bool status = pmcFileWriter.WriteFile();
    if (false == status)
    {
        LOG_ERROR << "Error creating PMC data file" << std::endl;
        m_Reply = "0xDEADDEAD\r\n";
        return 0;
    }

    // Reply with file size
    size_t pmcFileSize = pmcFileWriter.GetFileSize();

    std::ostringstream replyBuilder;
    replyBuilder << pmcFileSize << "\r\n";
    m_Reply = replyBuilder.str();

    return 0;
}

/*
*/
int CmdIface::cmd_read_pmc_file(unsigned int ref_number)
{
    LOG_DEBUG << "Reading PMC File #" << ref_number << std::endl;

    PmcFile pmcFile(ref_number);

    if (NULL == pmcFile.GetFileName())
    {
        LOG_ERROR << "Error getting PMC data file #" << ref_number << std::endl;
        m_Reply = "0xDEADDEAD\r\n";
        return 0;
    }

    // Note: No \r\n is needed here, the file name won't be sent to a clientls
    m_Reply = pmcFile.GetFileName();
	replyType = REPLY_TYPE_FILE;
    return 0;
}

/*
*/
int CmdIface::cmd_rb(char *interface, unsigned int address, unsigned int num_regs)
{
    void *handler = get_interface(interface);

    if((handler == NULL) || (num_regs > MAX_REGS_LEN))
    {
        m_Reply = "0xDEADDEAD\r\n";
        return 0;
    }

    unsigned int *val = new unsigned int[num_regs];

    if (!val)
    {
        m_Reply = "0xDEADDEAD\r\n";
        return 0;
    }

    int rc = readBlock(handler, address, num_regs*sizeof(unsigned int), (char*)val);

    if (rc == 0)
    {
        std::ostringstream replyBuilder;
        replyBuilder << std::hex;

        for(unsigned int i=0; i < num_regs; i++)
        {
            replyBuilder << "0x" << val[i];
            if(i < num_regs -1 )
            {
                replyBuilder << ' ';
            }
        }

        replyBuilder << "\r\n";
        m_Reply = replyBuilder.str();
    }
    else
    {
        m_Reply = "0xDEADDEAD\r\n";
    }

    delete[] val;
    return 0;
}

/*
*/
int CmdIface::cmd_wb(char *interface, unsigned int address, unsigned int len, const char *block)
{
    void *handler = get_interface(interface);

    if((handler == NULL) || (len > MAX_REGS_LEN))
    {
        m_Reply = "0xDEADDEAD\r\n";
        return 0;
    }

    LOG_VERBOSE << "current WB is " << block << " length is " << len << std::endl;
    int rc = writeBlock(handler, address, len, block);
    if(rc == 0)
    {
        m_Reply = "0\r\n";
    }
    else
    {
        m_Reply = "ERROR\r\n";
    }

    return 0;
}


int CmdIface::cmd_interface_reset(char *interface)
{
    void *handler = get_interface(interface);
    if(handler == NULL)
    {
        m_Reply = "0xDEADDEAD\r\n";
	}
    else
	{
        int rc = InterfaceReset(handler);
        if(rc == 0)
		{
            m_Reply = "OK\r\n";
		}
        else
		{
            m_Reply = "0xDEADDEAD\r\n";
		}
    }

    return 0;
}


int CmdIface::cmd_sw_reset(char *interface)
{
	void *handler = get_interface(interface);
	if (handler == NULL)
	{
		m_Reply = "0xDEADDEAD\r\n";
	}
	else
	{
		int rc = SwReset(handler);
		if (rc == 0)
		{
			m_Reply = "OK\r\n";
		}
		else
		{
			m_Reply = "0xDEADDEAD\r\n";
		}
	}

	return 0;
}

int CmdIface::cmd_set_host_alias(char* alias)
{
	std::ofstream fd(UdpServer::host_details_file_name.c_str());
	if (!fd.is_open())
	{
		m_Reply = "FAIL : Coudn't set the new alias: failed to open the configuration file";
		LOG_VERBOSE << m_Reply << std::endl;
		return -1;
	}
	fd << alias;
	if (fd.bad())
	{
		m_Reply = "FAIL : Coudn't set the new alias: failed to write the new alias to the configuration file";
		LOG_VERBOSE << m_Reply << std::endl;
		fd.close();
		return -2;
	}
	fd.close();

	UdpServer::SetHostAlias(alias);
	UdpServer::SendAll(UdpServer::GetHostDetails());
	return 0;
}


/*
 Execute command received from a remote client
 The command of length 'len' is in 'buf'. 'outlen' has
 the max output buffer size.
 On return, 'outbuf' may have a reply to be sent to the client,
 'outlen' should have the reply length or 0 if no reply required.
 Returns KEEPALIVE_OK if ok, KEEPALIVE_CLOSE to close the connection, KEEPALIVE_SHUTDOWN to shutdown the server (debug mode)
*/
int CmdIface::do_command(const char *buf, int len)
{
    servercmd_t s;
    int result = KEEPALIVE_OK;
    replyType = REPLY_TYPE_BUFFER;

    ((char*)buf)[len] = '\0';	// Make a zero-terminated string

    // Parse the command
    parse_line(buf, &s);
    dump_parser(&s);

    // Check for the parser error. Note, not all the commands in the original protocol report about errors. so we check the error
    // for selected commands only TODO: verify the commands list reporting the error
    if(s.cmd == CMD_OPEN_INTERFACE || s.cmd == CMD_R || s.cmd == CMD_RB || s.cmd == CMD_W || s.cmd == CMD_WB)
    {
        if(s.error != 0)
        {
            LOG_ERROR << "Command line parsing error" << std::endl;
            m_Reply = "0xDEADDEAD\r\n";    // TODO: or should it be "dmtools_error"??
            return result;
        }
    }

    switch(s.cmd)
    {
    case CMD_GET_INTERFACES:
        cmd_get_interfaces();
        break;
    case CMD_OPEN_INTERFACE:
        cmd_open_interface(s.interface);
        break;
    case CMD_CLOSE_INTERFACE:
        cmd_close_interface(s.interface);
        break;
    case CMD_R:
        cmd_r(s.interface, s.address);
        break;
    case CMD_RB:
        cmd_rb(s.interface, s.address, s.value);
        break;
    case CMD_W:
        cmd_w(s.interface, s.address, s.value);
        break;
    case CMD_WB:
        // hexdata_len is in dwords, cmd_wb works in bytes. (hence * 4)
        cmd_wb(s.interface, s.address, s.hexdata_len * 4, (const char*)s.hexdata);
        break;
    case CMD_INTERFACE_RESET:
        cmd_interface_reset(s.interface);
        break;
    case CMD_SW_RESET:
	cmd_sw_reset(s.interface);
	break;
    case CMD_EXIT:
        result = KEEPALIVE_CLOSE;   // Terminate the connection
        break;
    case CMD_ALLOC_PMC:
        cmd_alloc_pmc(s.interface, s.address, s.value);
        break;
    case CMD_READ_PMC:
        cmd_read_pmc(s.interface, s.address);
        break;
    case CMD_READ_PMC_FILE:
        cmd_read_pmc_file(s.address);
        break;
	case CMD_SET_HOST_ALIAS:
		cmd_set_host_alias(s.interface);
		break;
    case CMD_COMMAND_UNKNOWN:
    default:
        m_Reply = "dmtools_error\r\n";

    }
    return result;
}

/*
 Dump the parser structure, for debugging only
*/
void CmdIface::dump_parser(servercmd_t *s)
{
    if(s->error)
    {
        LOG_ERROR << "Parser error in comand parsing."
            << " Error: " << s->error
            << " Message: " << parser_error_to_string(s->error)
            << std::endl;

        return;
    }

    LOG_VERBOSE << "Parsed Command: " << command_to_string(s->cmd)
                << " Interface: " <<  s->interface  << std::endl;

    if(s->address != (unsigned int)-1)
    {
        LOG_VERBOSE << "Address: " << s->address << std::endl;
    }
    if(s->value != (unsigned int)-1)
    {
        LOG_VERBOSE << "Value: " << s->value << std::endl;
    }
    if(s->hexdata_len)
    {
        for(int i=0; i < s->hexdata_len && i < MAX_REGS_LEN; i++)
            LOG_VERBOSE << std::hex << "0x" << s->hexdata[i] << std::dec << std::endl;
    }
}

/*
*/
int CmdIface::get_reply_len()
{
    return m_Reply.size();
}

/*
*/
void CmdIface::to_lower(char* string)
{
    for (int i = 0; string[i]; i++)
    {
	string[i] = tolower(string[i]);
    }

    return;
}

/*
*/
CmdIface::CmdIface()
    : replyType(REPLY_TYPE_BUFFER)
{
}
