<?php

/*
 * TODO
 *  Better logging instantiation/customization
 *  Config handling class
 *  Make it easier to set response code and output error
 *  Check user<->game permissions
 *  should login care about roles? or is that job for getUserInfo?
 */

require_once 'Outspark/3rdparty/Restafarian/restafarian_common.php';
require_once '../OSKSignedRestResource.inc';
require_once '../OSKUserModel.inc';
require_once 'Outspark/Common/KeyMaster/KeyMaster.php';
require_once 'Outspark/Platform/OutsparkUser/OSKUser.php';
require_once 'Outspark/Platform/Ruxpin/Ruxpin.php';
require_once 'Outspark/Platform/AvatarProfile/AvatarProfile.php';

define('MEEBO_AUTH_USERNAME', 1001);
define('MEEBO_AUTH_UID', 1002);

// Set up logging
if (!class_exists('Log')) {
    include 'Log.php';
}
$GLOBALS['logger'] = Log::factory('file', '', 'UserResource');
if (is_null($GLOBALS['logger'])) {
    exit("Unable to initiate Logging");
}
$GLOBALS['logger']->setMask(PEAR_LOG_ALL);

$GLOBALS['conf'] = parse_ini_file('/var/www/conf/restconf.ini', true);

class MeeboResource extends OSKRestResource
{
    public function dispatch ($req)
    {
        $next = $this;
        $version = $this->getNextRawSegment();

        /*
         * If version doesn't match, return /user resource
         */
        if ($version != 'v1') {
            return $this;
        }

        /*
         * Get the portion after version
         */
        $this->incrementNextIndex();
        $segment = $this->getNextRawSegment();

        switch ($segment) {
            case 'authenticateusername':
                $next = new MeeboAuthenticationResource(MEEBO_AUTH_USERNAME);
                break;
            case 'authenticateuid':
                $next = new MeeboAuthenticationResource(MEEBO_AUTH_UID);
                break;
            case 'getfriends':
                $next = new MeeboFriendsListResource();
                break;
            case 'getinfo':
                $next = new MeeboUserInfoResource();
                break;
            case 'usernameexists':
                $next = new MeeboUserExistsResource(MEEBO_AUTH_USERNAME);
                break;
            case 'uidexists':
                $next = new MeeboUserExistsResource(MEEBO_AUTH_UID);
                break;
            case 'authenticatetoken':
                $next = new MeeboAuthenticationTokenResource();
                break;
            case 'statuschange':
                $next = new MeeboStatusChangeResource();
                break;
            case 'notificationsread':
            case 'addfriendrequest':
            case 'blocked':
            case 'abusereported':
                $next = new MeeboStatusOKResource();
                break;        
            default:
                // no default action
                break;
        }

        return $next;
    }

    public function GET ($req, $resp)
    {
        /*
         * Anything not handled under /user is an error.
         */
        $resp->setStatusCode(REST_STATUS_BAD_REQUEST);
        $resp->makeError($this, $resp->getStatusCode(), "Bad Request");
    }
}

class MeeboAuthenticationTokenResource extends OSKRestResource {
    public function GET($req, $resp){
        return $this->POST($req, $resp);
    }
    
    public function POST($req, $resp){

        $conf = $GLOBALS['conf'];

        $params = $req->getUri()->getQueryParams();
        //$user = $params->getFirst('uid');
        //$token = $params->getFirst('token');
        $user = $_REQUEST['uid'];
        $token = $_REQUEST['token'];

        $userInfo = false;

        $output = isset($_REQUEST['output'])? $_REQUEST['output']:'json';

        $result = array();
        $result["stat"] = "fail";
        if (!(empty($user) || empty($token))) {
            try {
                $model = new OSKUserModel();
                $userInfo = $model->getUserInfoByUID($user);
                if ($userInfo) {
                    // grab the time from the end of the token
                    list($hash, $time) = explode(".", $token, 2);
                    if(time() <= $time + (60 * 60 * 24 * 14)){ // two weeks
                        // lookup the token secret
                        $S1 = OSKKeyMaster::getInstance()->getKey('meebo.token');
                        // generate token as: H(S1 + H(P + T))
                        $local_hash = hash("sha256", $S1.hash("sha256", $userInfo['password'].$time));
                        // compare tokens. if they match, we're golden
                        if($local_hash == $hash){
                            $result["stat"] = "ok";
                            $result["data"] = array("authenticated" => true, "uid" => $userInfo["userid"], "name" => $userInfo["sparkid"]);
                        }else{
                            $result["stat"] = "ok";
                            $result["data"] = array("authenticated" => false);
                        }
                    }else{
                        $result["stat"] = "ok";
                        $result["data"] = array("authenticated" => false);
                    }
                }else{
                    $result["errorcode"] = 400;
                    $result["msg"] = "User id not found";
                }
            } catch (Exception $e) {
                $result["errorcode"] = 500;
                $result["msg"] = "Unable to look up user";
            }
        }else{
            $result["errorcode"] = 400;
            $result["msg"] = "Missing required parameter.";            
        }
        
        $json = json_encode($result);

        if ($output == 'text') {
            $resp->setContent(CTYPE_TEXT, $json);
        } else {
            $resp->setContent(CTYPE_JSON, $json);
        }
        
        $resp->setStatusCode(REST_STATUS_OK);
    }
}

class MeeboStatusOKResource extends OSKRestResource {
    public function GET($req, $resp){
        return $this->POST($req, $resp);
    }
    
    public function POST($req, $resp){
        $response = array();
        $response["stat"]= "ok";
        
        $json = json_encode($response);
        
        $output = isset($_REQUEST['output'])?$_REQUEST['output']:'text';
        if ($output == 'text') {
            $resp->setContent(CTYPE_TEXT, $json);
        } else {
            $resp->setContent(CTYPE_JSON, $json);
        }
        
        $resp->setStatusCode(REST_STATUS_OK);
        
    }
}
class MeeboUserInfoResource extends OSKRestResource {
    
    public function GET($req, $resp){
        $response = array();
        $response["stat"]= "fail";
        
        $params = $req->getUri()->getQueryParams();
        $uid = $_REQUEST['uid'];//$params->getFirst('uid');
        
        $user = OSKUser::getByUserID($uid);
        $profile = $user->getProfile();
        
        $avatarprofile = new AvatarProfile();
        
        $response["stat"] = "ok";
        $response["data"] = array();
        
        $image = $avatarprofile->getProfileImage($uid, AvatarProfile::PROF_IMAGE_THUMB, $junk);
        if($image){
            $response["data"]["imageurl"] = $image;
        }
        
        $status = $avatarprofile->getStatusMessage($uid, $junk);
        if($status){
            $response["data"]["status"] = $status;
        }
        
        $gender = $profile["gender"];
        if($gender){
            $response["data"]["gender"] = $gender;
        }
        
        $json = json_encode($response);
        
        $output = $params->getFirst('output');
        if ($output == 'text') {
            $resp->setContent(CTYPE_TEXT, $json);
        } else {
            $resp->setContent(CTYPE_JSON, $json);
        }
        
        $resp->setStatusCode(REST_STATUS_OK);
        
    }
    
}

class MeeboFriendsListResource extends OSKRestResource {
    public function GET($req, $resp){
        $response = array();
        $response["stat"]= "fail";
        
        $params = $req->getUri()->getQueryParams();
        $user = $_REQUEST['uid'];// $params->getFirst('uid');
        
        $ruxpin = new Ruxpin($user);
        $output = $params->getFirst('output');
        if (empty($output)) {
            $output = 'json';
        }

        $result = array();
        $result["stat"] = "ok";
        
        $buddies = $ruxpin->getBuddies();
        $result["data"]["friendresponse"] = "full";
	$result["data"]["friends"] = array();
        foreach($buddies as $buddy){
            $result["data"]["friends"][] = array("uid" => $buddy->uid, "name" => $buddy->sparkid);
        }
        
                $json = json_encode($result);

        if ($output == 'text') {
            $resp->setContent(CTYPE_TEXT, $json);
        } else {
            $resp->setContent(CTYPE_JSON, $json);
        }
        
        $resp->setStatusCode(REST_STATUS_OK);
        
    }
}

class MeeboAuthenticationResource extends OSKRestResource {
    
    private $authtype;
    
    public function __construct($auth_type){
        $this->authtype = $auth_type;
        parent::__construct();
    }
    
    public function GET ($req, $resp){
        return $this->POST($req, $resp);
    }    
    public function POST ($req, $resp)
    {
        $conf = $GLOBALS['conf'];
        
        $response = array();
        $response["stat"]= "fail";
        
        $user = false;
        
        $params = $req->getUri()->getQueryParams();
        if($this->authtype == MEEBO_AUTH_UID){
            $user = is_numeric($_REQUEST['uid'])?$_REQUEST['uid'] : -1;//$params->getFirst('uid');
        }else{
            $user = $_REQUEST['username'];//$params->getFirst('username');
        }
        $pass = $_REQUEST['password'];//$params->getFirst('password');

        $userInfo = false;

        $realm = "meebo";

        $output = $params->getFirst('output');
        if (empty($output)) {
            $output = 'json';
        }

        $result = array();
        $result["stat"] = "fail";
        if ( !empty($user) && !empty($pass) ) {
            try {
                $model = new OSKUserModel();
                if($this->authtype == MEEBO_AUTH_UID){
                    $userInfo = $model->getUserInfoByUID($user);
                }else{
                    $userInfo = $model->getUserInfo($user);
                }
                if ($userInfo) {
                    // Deny access to users who are unverified or banned
                    if (!empty($userInfo['status'])) {
                        if (!empty($userInfo['verified'])) {
                            $result["stat"] = "ok";    
                            if ( ($userInfo['password'] != $pass) && ($userInfo['password'] != md5($pass)) ) { // check to work around reg issue where 54k users had their passwords double hashed
                                $result["data"] = array("authenticated" => false);
                            }else{
                                $result["data"] = array("authenticated" => true, "uid"=> $userInfo["userid"], "name" => $userInfo["sparkid"]);
                            }
                        }else{
                            // not verified
                            $result["stat"] = "ok";
                            $result["data"] = array("authenticated" => false);
                        }
                    }else{
                        $result["stat"] = "ok";
                        $result["data"] = array("authenticated" => false);          
                    }
                }else{
                    $result["stat"] = "ok";
                    $result["data"] = array("authenticated" => false);           
                }
            } catch (Exception $e) {
                $result["stat"] = "ok";
                $result["data"] = array("authenticated" => false);
            }
        }else{
            $result["errorcode"] = 400;
            $result["msg"] = "Missing required parameters. Check your username and password";            
        }
        
        $json = json_encode($result);

        if ($output == 'text') {
            $resp->setContent(CTYPE_TEXT, $json);
        } else {
            $resp->setContent(CTYPE_JSON, $json);
        }
        
        $resp->setStatusCode(REST_STATUS_OK);
    }

}

class MeeboUserExistsResource extends OSKRestResource {
    
    private $authtype;
    
    public function __construct($auth_type){
        $this->authtype = $auth_type;
        parent::__construct();
    }
    
    public function GET ($req, $resp){
        return $this->POST($req, $resp);
    }
    
    public function POST ($req, $resp)
    {
        $conf = $GLOBALS['conf'];
        
        $response = array();
        $response["stat"]= "fail";
        
        $user = false;
        
        $params = $req->getUri()->getQueryParams();
        if($this->authtype == MEEBO_AUTH_UID){
            $user = is_numeric($_REQUEST['uid'])?$_REQUEST['uid']: false;//$params->getFirst('uid');
        }else{
            $user = $_REQUEST['username'];//$params->getFirst('username');
        }

        $userInfo = false;

        $output = $params->getFirst('output');
        if (empty($output)) {
            $output = 'json';
        }

        $result = array();
        $result["stat"] = "fail";
        if (!(empty($user))) {
            try {
                $model = new OSKUserModel();
                if($this->authtype == MEEBO_AUTH_UID){
                    $userInfo = $model->getUserInfoByUID($user);
                }else{
                    $userInfo = $model->getUserInfo($user);
                }
                if ($userInfo) {
                    // Deny access to users who are unverified or banned
                    $result["stat"] = "ok";    
                    $result["data"] = array("exists" => true, "uid"=> $userInfo["userid"], "name" => $userInfo["sparkid"]);
                }else{
                    $result["stat"] = "ok";
                    $result["exists"] = false;
                }
            } catch (Exception $e) {
                    $result["stat"] = "ok";
                $result["exists"] = false;            
            }
        }else{
            $result["errorcode"] = 400;
            $result["msg"] = "Missing required parameter.";            
        }
        
        $json = json_encode($result);

        if ($output == 'text') {
            $resp->setContent(CTYPE_TEXT, $json);
        } else {
            $resp->setContent(CTYPE_JSON, $json);
        }
        
        $resp->setStatusCode(REST_STATUS_OK);
    }

}




class MeeboStatusChangeResource extends OSKRestResource {
    
    public function POST($req, $resp){
        $response = array();
        $response["stat"]= "ok";
        
        $params = $req->getUri()->getQueryParams();
        $uid = $params->getFirst('uid');
        $status = $params->getFirst('status');
        
        if( isset($uid, $status) ){
            $response["stat"]= "ok";
        }else{
            $response["stat"]= "fail";
            $response["errorcode"] = 400;
            $response["msg"] = "Missing required parameters.";
        }

        $json = json_encode($response);
        
        $output = isset($_REQUEST['output'])?$_REQUEST['output']:'text';
        if ($output == 'text') {
            $resp->setContent(CTYPE_TEXT, $json);
        } else {
            $resp->setContent(CTYPE_JSON, $json);
        }
        
        $resp->setStatusCode(REST_STATUS_OK);
        
    }
}

?>
