/*
 * Copyright (c) 2014 Netflix, Inc.
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY NETFLIX, INC. AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED. IN NO EVENT SHALL NETFLIX 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 <string>
#include "DialDiscovery.h"
#include "DialConformance.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

using namespace std;

static DialDiscovery* gpDiscovery;
static bool gUseMenu = true;

// TODO: Make it possible to pass applications from the command line
static vector<string> gAppList;
static string gOutputFile;
static string gInputFile;

// IP address of the DIAL server
static string gIpAddress;

static void printServerList( vector<DialServer*> list )
{
    int i;
    vector<DialServer*>::iterator it;
    for( i = 0, it = list.begin(); it < list.end(); it++, i++ )
    {
        string uuid, name, macAddr;
        int wolTimeOut;
        (*it)->getFriendlyName( name );
        (*it)->getUuid( uuid );
        macAddr    =(*it)->getMacAddress();
        wolTimeOut =(*it)->getWakeOnLanTimeout();
        printf("%Zu: Server IP[%s] UUID[%s] FriendlyName[%s] MacAddress[%s] WakeOnLanTimeout[%d]\n", 
               i+1, (*it)->getIpAddress().c_str(),
               uuid.c_str(), name.c_str(), macAddr.c_str(), wolTimeOut);
    }
}

static DialServer* getServerFromUser( vector<DialServer*> list )
{
    DialServer* pServer;
    // show a list to the user
    char buf[80] = {0,};
    vector<DialServer*>::iterator it;

    printf("Found Multiple servers\n");
    printf("0: Rescan and list DIAL servers\n");
    printServerList(list);
    printf("Enter server: ");
    scanf("%s", buf);
    unsigned int server = atoi(buf);
    if( server > 0 && server <= list.size()){
        pServer = list[server-1];
    }else{
        pServer = NULL;
    }
    return pServer;
}

static void runConformance()
{
    vector<DialServer*> list;
    gpDiscovery->getServerList(list);

    if( list.size() )
    {
        DialServer *pServer = NULL;
        if( !gIpAddress.empty() )
        {
            pServer = NULL;
            vector<DialServer*>::iterator it;
            for( it = list.begin(); it < list.end(); it ++ )
            {
                if( gIpAddress.compare((*it)->getIpAddress()) == 0 )
                {
                    ATRACE("Found server %s in the list of servers\n", 
                                gIpAddress.c_str() );
                    pServer = (*it);
                    break;
                }
            }
        }
        else
        {
            pServer = getServerFromUser( list );
        }

        if( pServer )
        {
            string name;
            bool serverExists = pServer->getFriendlyName(name);
            assert( serverExists );
            string uuid;
            pServer->getUuid( uuid );
            printf("\nRunning conformance against: IP[%s] UUID[%s] FriendlyName[%s] \n", 
                    pServer->getIpAddress().c_str(),
                    uuid.c_str(), name.c_str() );
            DialConformance::instance()->run( 
                pServer, 
                gAppList, 
                gInputFile, 
                gOutputFile );
        }
        else 
        {
            printf("DIAL server not found\n");
            printf("%Zu available server(s): \n", list.size());
            printServerList(list);
        }
    }
    else
    {
        printf("No servers available\n");
    }
}

static void sendMagic(string macAddr)
{
    unsigned char tosend[102];
    unsigned char mac[6];

    /** first 6 bytes of 255 **/
    for(int i = 0; i < 6; i++) {
        tosend[i] = 0xFF;
    }

    /** store mac address **/
    printf("sending magic packet to: ");
    for (int i=0; i<6; i++){
        mac[i]=(unsigned char)(strtoul(macAddr.substr(i*3, 2).c_str(), NULL, 16));
        printf("%02x:", mac[i]);
    }
    printf("\n");

    /** append it 16 times to packet **/
    for(int i = 1; i <= 16; i++) {
        memcpy(&tosend[i * 6], &mac, 6 * sizeof(unsigned char));
    }

    int udpSocket;
    struct sockaddr_in udpClient, udpServer;
    int broadcast = 1;

    udpSocket = socket(AF_INET, SOCK_DGRAM, 0);

    /** you need to set this so you can broadcast **/
    if (setsockopt(udpSocket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof broadcast) == -1) {
        perror("setsockopt (SO_BROADCAST)");
        exit(1);
    }
    udpClient.sin_family = AF_INET;
    udpClient.sin_addr.s_addr = INADDR_ANY;
    udpClient.sin_port = 0;

    bind(udpSocket, (struct sockaddr*)&udpClient, sizeof(udpClient));

    /** set server end point (the broadcast addres)**/
    udpServer.sin_family = AF_INET;
    udpServer.sin_addr.s_addr = inet_addr("255.255.255.255");
    udpServer.sin_port = htons(9);

    /** send the packet **/
    sendto(udpSocket, &tosend, sizeof(unsigned char) * 102, 0, (struct sockaddr*)&udpServer, sizeof(udpServer));
}


int handleUser(DialDiscovery *pDial) {
    int processInputOuter = 1;        
    char buf[80];
    vector<DialServer*> list;
    
    while (processInputOuter){
        pDial->getServerList(list);
        if( list.size() == 0 ){
            printf("No servers available\n");
            return 1;
        }
        DialServer* pServer = getServerFromUser( list );
        if (pServer==NULL){
            pDial->send_mcast();
            continue;
        }

        int processInput = 1;        
        while(processInput){
            string responseHeaders, responseBody, payload;
            string netflix = "Netflix";
            string youtube = "YouTube";
            
            memset(buf, 0, 80);
            printf("0. Rescan and list DIAL servers\n");
            printf("1. Launch Netflix\n");
            printf("2. Kill Netflix\n");
            printf("3. Netflix status\n");
            printf("4. Launch YouTube\n");
            printf("5. Kill YouTube\n");
            printf("6. YouTube status\n");
            printf("7. Run conformance tests\n");
            printf("8. Wake up on lan/wlan\n");
            printf("9. QUIT\n");
            printf("Command (0:1:2:3:4:5:6:7:8:9): ");
            scanf("%s", buf);
            switch( atoi(buf) )
                {
                case 0:
                    {
                        pDial->send_mcast();
                        processInput=0;
                    }break;
                case 1:
                    printf("Launch Netflix\n");
                    pServer->launchApplication( netflix, payload, responseHeaders, responseBody );
                    break;
                case 2:
                    printf("Kill Netflix\n");
                    pServer->stopApplication( netflix, responseHeaders );
                    break;
                case 3:
                    printf("Netflix Status: \n");
                    pServer->getStatus( netflix, responseHeaders, responseBody );
                    printf("RESPONSE: \n%s\n", responseBody.c_str());
                    break;
                case 4:
                    printf("Launch YouTube\n");
                    pServer->launchApplication( youtube, payload, responseHeaders, responseBody );
                    break;
                case 5:
                    printf("Kill YouTube\n");
                    pServer->stopApplication( youtube, responseHeaders );
                    break;
                case 6:
                    printf("YouTube Status: \n");
                    pServer->getStatus( youtube, responseHeaders, responseBody );
                    break;
                case 7:
                    runConformance();
                    break;
                case 8:
                    printf("Sending the magic packet\n");
                    sendMagic(pServer->getMacAddress());
                    break;
                case 9:
                    processInput = 0;
                    processInputOuter = 0;
                    break;
                default:
                    printf("Invalid, try again\n");
                }
        } 
    }
    return 0;
}

static const char usage[] = "\n"
" If no option is specified, the program will run a conformance test.\n"
"\n"
"usage: dialclient <option>\n"
" Option Parameter              Description\n"
" -h     none                   Usage menu\n"
" -s     filename (optional)    Run conformance test.  Use filename as\n"
"                               the input, if provided\n"
" -o     filename               Reporter output file (./report.html)\n"
" -a     ip_address             IP address of DIAL server (used for conformance\n"
"                               testing)\n"
"\n";

inline void notSupported( string s )
{
    printf( "%s not supported", s.c_str() );
    printf( "%s\n", usage );
    exit(0);
}

int parseArgs( int argc, char* argv[] )
{
    for( int i = 1; i < argc; i++ )
    {
        string input(argv[i]);
        if( input[0] != '-' ) notSupported(input);
        switch(input[1])
        {
        case 's':
            gUseMenu = false;
            if( argv[i+1] != NULL && argv[i+1][0] != '-' )
            {
                //filename provided
                gInputFile = argv[++i];
            }
            break;
        case 'o':
            gOutputFile = argv[++i];
            break;
        case 'a':
            gIpAddress = argv[++i];
            break;
        case 'h':
            printf("%s", usage);
            exit(0);
            break;
        default:
            notSupported(input);
        }
    }
    return 0;
}

int main(int argc, char* argv[]) {
    parseArgs(argc, argv);

    gpDiscovery = DialDiscovery::create();
    gpDiscovery->init();
    DialConformance::create();

    // Sleep for 2 seconds to allow DIAL servers to response to MSEARCH.
    sleep(2);

    if ( gUseMenu )
    {
        return handleUser(gpDiscovery);
    }

    // not using the menu, just run the conformance test.
    runConformance();
    return 0;
}

