#include "fcgi_stdio.h"
#include "../include/YT_EHOME_shm.h"
#include <stdlib.h>
#include <string.h>
#include <json-c/json.h>
#include <ctype.h>

MyEHomeShm *ytShm;



unsigned char* urldecode(char *string)
{
        int destlen = 0;
        unsigned char *src, *dest;
        unsigned char *newstr;

        if (string == NULL) return NULL;

        for (src = (unsigned char *)string; *src != '\0'; src++)
 {
                if (*src == '%')
  {
   destlen++;
  }
        }

        newstr = (unsigned char *)malloc(destlen + 1);
        src = (unsigned char *)string;
        dest = newstr;

        while (*src != '\0')
 {
                if (*src == '%')
  {
                        char h = toupper(src[1]);
                        char l = toupper(src[2]);
                        int vh, vl;
                        vh = isalpha(h) ? (10+(h-'A')) : (h-'0');
                        vl = isalpha(l) ? (10+(l-'A')) : (l-'0');
                        *dest++ = ((vh<<4)+vl);
                        src += 3;
                } else if (*src == '+') {
                        *dest++ = ' ';
                        src++;
                } else {
                        *dest++ = *src++;
                }
        }
        *dest = 0;

        return newstr;
}
bool shm_load()
{
    int shmid;
    key_t key;
    if((key = ftok(SHM_PATH,(int)SHM_PORT))==-1)
        return false;
    if((shmid = shmget(key,sizeof(MyEHomeShm),IPC_CREAT|0666))==-1)
        return false;
    ytShm = (MyEHomeShm *)shmat(shmid,NULL,0);
    return true;
}

json_object *get_hc_list(){
    int i;
    json_object *obj;
    json_object *list = json_object_new_array();
    char tmp[256];
    for(i=0;i<DEVICES_COUNT;i++){
        if(ytShm->eHomeDevice[i].io[8]!=0x00)
        {
            obj = json_object_new_object();
            sprintf(tmp,"%s",ytShm->eHomeDevice[i].deviceID);
            json_object_object_add(obj,"ID",json_object_new_int(i+1));
            json_object_object_add(obj,"DEVICE",json_object_new_string((const char *)tmp));
            if(ytShm->eHomeDevice[i].io[8]==0x01)
                json_object_object_add(obj,"LIVEONLINE",json_object_new_boolean(true));
            else
                json_object_object_add(obj,"LIVEONLINE",json_object_new_boolean(false));
            if(ytShm->eHomeDevice[i].transed==0x01)
                json_object_object_add(obj,"ONAIR",json_object_new_boolean(true));
            else
                json_object_object_add(obj,"ONAIR",json_object_new_boolean(false));

            json_object_object_add(obj,"ALIVEVALUE",json_object_new_int(ytShm->eHomeDevice[i].io[14]&0xff));
            json_object_array_add(list,obj);
        }
    }
    return list;
}

json_object *get_cu_list(){
    int i;
    json_object *obj;
    json_object *list = json_object_new_array();
    char tmp[256];
    for(i=0;i<DEVICES_COUNT;i++){
        if(ytShm->eHomeDevice[i].Connected==0x01){
            obj = json_object_new_object();
            sprintf(tmp,"%s",ytShm->eHomeDevice[i].deviceID);
            json_object_object_add(obj,"ID",json_object_new_int(i+1));
            json_object_object_add(obj,"DEVICE",json_object_new_string((const char *)tmp));
            json_object_array_add(list,obj);
        }
    }
}

bool active_live(json_object *q_body){
    json_object *q_device=NULL, *q_act=NULL, *q_idx=NULL;
    int act=-1,idx=0,i;
    char deviceId[256],tmp[256];
    json_object_object_foreach(q_body,key,val){
        if(strcmp(key,"DEVICE")==0)
            q_device = val;
        else if(strcmp(key,"ACTION")==0)
            q_act = val;
        else if(strcmp(key,"IDX")==0){
            q_idx = val;
            if(json_object_get_type(q_idx)==json_type_int)
                idx = json_object_get_int(q_idx);
        }
    }
    if((NULL!=q_device)&&(NULL!=q_act)&&(json_object_get_type(q_device)==json_type_string)&&(json_object_get_type(q_act)==json_type_int)){
        sprintf(deviceId,"%s",json_object_get_string(q_device));
        act = json_object_get_int(q_act);
        if((act==0x00)||(act==0x01)){
            for(i=0;i<DEVICES_COUNT;i++){
                if(ytShm->eHomeDevice[i].Inited==0x01){
//                    sprintf(tmp,"%s",ytShm->eHomeDevice[i].deviceID);
                    if(strcmp(ytShm->eHomeDevice[i].deviceID,deviceId)==0){
                        if((idx>=0)&&(idx<8)){
                            ytShm->eHomeDevice[i].io[idx]=act;
                            return true;
                        }else
                            return false;
                    }
                }
            }
        }
    }
    return false;
}

bool json_request_action(char *request, json_object *body){
    json_object *q_json = NULL, *q_body =NULL, *q_cmd = NULL;
    int cmd;
    q_json = json_tokener_parse(request);
    if(q_json!=NULL){
//        json_object_object_add(body,"QUERY",q_json);
        json_object_object_foreach(q_json,key,val){
            if(strcmp(key,"CMD")==0)
                q_cmd = val;
            else if(strcmp(key,"BODY")==0)
                q_body = val;
        }
        if(NULL!=q_cmd){
            if(json_object_get_type(q_cmd)==json_type_int){
                cmd = json_object_get_int(q_cmd);
                switch (cmd) {
                case GET_LIVE_LIST:
                    json_object_object_add(body,"CMD",json_object_new_int(cmd));
                    json_object_object_add(body,"LIST",get_hc_list());
                    break;
                case GET_ONLINE_LIST:
                    json_object_object_add(body,"CMD",json_object_new_int(cmd));
                    json_object_object_add(body,"LIST",get_cu_list());
                    break;
                case ACTIVE_LIVE:
                    json_object_object_add(body,"CMD",json_object_new_int(cmd));
                    if(active_live(q_body))
                        json_object_object_add(body,"ACTION",json_object_new_int(1));
                    else
                        json_object_object_add(body,"ACTION",json_object_new_int(0));
                    break;
                default:
                    json_object_object_add(body,"RESULT",json_object_new_int(0));
                    break;
                }
            }
        }else{
            json_object_put(q_json);
            return false;
        }
        json_object_put(q_json);
    }else
        return false;
    return true;
}

int main(void)
{
    int i;
    char input[1024],lenstr[60],data[1024];
    int len;
    json_object *json,*json_body;
    if(shm_load()){
        while (FCGI_Accept() >= 0){
            sprintf(lenstr,"%s",getenv("CONTENT_LENGTH"));
            len = atoi(lenstr);
            if((len>0)&&(len<1024)){
                bzero(input,sizeof(input));
                bzero(data,sizeof(data));
                fgets(input,len+1,stdin);
                for(i=0;i<(len-10);i++)
                    data[i] = input[10+i];
                json = json_object_new_object();
                json_body = json_object_new_object();
                if(json_request_action(data,json_body)){
                    json_object_object_add(json,"RESULT",json_body);
                    json_object_object_add(json,"REPLY",json_object_new_int(1));
                }else{
                    json_object_object_add(json,"REPLY",json_object_new_int(0));
                }
                json_object_object_add(json,"QUERY",json_object_new_string(data));
                printf("Access-Control-Allow-Origin: *\r\n");
                printf("Content-type: text/html\r\n\r\n%s",json_object_to_json_string(json));
                json_object_put(json);
            }
        }
        shmdt(ytShm);
    }
    return 0;
}

