#include <stdio.h>
#include <string.h>
#include <cjson/cJSON.h>
#include "web_auth.h"
#include "user_hashtable.h"


/*输入参数:用户名、密码,json格式*/
/*输出参数:resultcode、描述信息message、剩余锁定时间remain_lock_time(认证成功和失败的情况下,剩余锁定时间默认为0) */
/*location:url location之后,get(方法判断是否是get方法) url的时候要判断下这个用户是否已经认证过*/


/* 用户认证 */
void user_auth_login(char* username, char* password, USER_AUTH_RET* auth_result);

char * mes[]={"SUCCESS", "ErrorUsernameOrpassword", "NotInVaildTime",
             "OutMaxOnlineNum", "UserIsLocked", "LackConfigInfo",
             "OverMaxOnlineNum", "OtherErr"};


/*content形式: {"username":"adimn", "password":"admin"} */
ret_code user_auth(pointer content, RESULT *uresult)
{
    ret_code ret = RET_OK;
    cJSON *cjson;
    USER_AUTH_RET *resultinfo;
    time_t time = 0;

    memset(uresult, 0, sizeof(RESULT));

    /*创建内存地址 */
    resultinfo = (USER_AUTH_RET *)malloc(sizeof(USER_AUTH_RET));
    if (NULL == resultinfo)
    {
        ret = RET_NOMEM;
        return ret;
    }

    /*JSON字符串到JSON格式 */
    cjson = cJSON_Parse(content);
    if(!cjson)
    {
        ret = RET_INPUTERR;
        return ret;
    }
    
    /*获取用户名 */
    char *uname = cJSON_GetObjectItem(cjson , "username")->valuestring;
    printf("username :%s\n", uname);

    /*判断username长度是否正确*/
    if( strlen(uname) > USERNAME_MAXLEN )
    {
        cJSON_Delete(cjson);
        ret = RET_IPINVALID;
        return ret;
    }
   
    /*获取密码 */
    char *upwd = cJSON_GetObjectItem(cjson, "password")->valuestring;
    printf("password :%s\n", upwd);
 
    /*判断password长度是否正确 */
    if( strlen(upwd) > PASSWORD_MAXLEN )
    {   
        cJSON_Delete(cjson);
        ret = RET_IPINVALID;
        return ret;
    }


    /*调用认证接口函数 */
    user_auth_login(uname, upwd, resultinfo);
    printf("认证结束\n");
    
    /*认证成功 */
    if (resultinfo->ret == 0)
    {
        printf("认证成功\n");
        uint32_t client_ip=10001;  /*解析报文拿到用户IP */
        printf("client_ip :%d\n", client_ip);
        Init_hash();  /*初始化hash表放在配置恢复处 */
        

        /*重定向到认证成功界面-调用web server提供的接口,发送url地址给接口,实现重定向 */
 

        /*客户端访问认证成功界面方法:GET */
        char method[10] = {"GET"};


        /*如果method是GET,判断这个用户是否认证过*/
        if(0 == strncmp(method, "GET",10))
        {
            struct user_info * uinfo;
            uinfo = (struct user_info *)malloc(sizeof(struct user_info));
            if (NULL == uinfo)
            {
                cJSON_Delete(cjson);  
                ret = RET_NOMEM;
                return ret;
            }

            /*用户认证过则跳出语句,不访问认证成功界面 */
            uinfo = ufind_user(client_ip);
           
            if ( NULL != uinfo )
            {
                printf("用户已经认证过\n");  
                free(uinfo);
                cJSON_Delete(cjson);
                ret = RET_ERR;
                return ret ;
            }
        
            uadd_user(client_ip,resultinfo->user_id);
            uprintf_users();

            uresult->resultcode = resultinfo->ret;
            uresult->remain_lock_time = time;
            uresult->message = mes[resultinfo->ret];
            printf("resultcode:%d remain_lock_time:%d message:%s\n",uresult->resultcode,
                                uresult->remain_lock_time, uresult->message );

        
        free(uinfo); 
        cJSON_Delete(cjson);  
        return ret;
        }
    }

    /*认证锁定*/
    if (resultinfo->ret == 4)
    {
        time = resultinfo->remain_lock_time;

        uresult->resultcode = resultinfo->ret;
        uresult->remain_lock_time = time;
        uresult->message = mes[resultinfo->ret];
        printf("resultcode:%d remain_lock_time:%d message:%s\n",uresult->resultcode,
                                uresult->remain_lock_time, uresult->message );
         
        cJSON_Delete(cjson); 
        ret = RET_ERR;
        return ret;
    }

     /*认证失败*/
    if ( (resultinfo->ret != 4) && (resultinfo->ret != 0))
    {
        printf("the value of resultcode is %d\n", resultinfo->ret);
        uresult->resultcode = resultinfo->ret;
        uresult->remain_lock_time = time;
        uresult->message = mes[resultinfo->ret];
        printf("resultcode:%d remain_lock_time:%d message:%s\n",uresult->resultcode,
                                uresult->remain_lock_time, uresult->message );
        
        cJSON_Delete(cjson); 
        ret = RET_ERR;
        return ret;
    }


    cJSON_Delete(cjson); 
	return ret;
}