/**
 * 对 apiMessage 进行适配，使其能够返回 PPMessage 的数据结构表示
 *
 * new ApiMessageAdapter(apiMessageJsonBody)
 *     .asyncGetPPMessage(function(ppMessage, success) {
 *         console.log("success: " + success + ", ppMessageJsonBody: " + ppMessage.getBody());
 *     });
 *
 * Date.now(): 1449716881332
 * apiMessage.ts: 1449649351.0 [IN SECONDS !!!]
 *
 * Date.parse("2015-12-10 09:55:35"); // 1449712535000
 * Date.parse("2015-12-10 09:55:35 719794"); // NaN
 *
 */
((function(Service) {

    function ApiMessageAdapter(apiMessageJsonBody) {

        var $json = Service.$json,
            $tools = Service.$tools,
            $emoji = Service.$emoji,
            $users = Service.$users,
            $user = Service.$user,

            apiMessageType = Service.Constants.MESSAGE_SUBTYPE,
            ppMessageType = Service.PPMessage.TYPE,
            
            apiMessage = apiMessageJsonBody,

            getMessageType = function(apiMessage) {
                var type = '',
                    msg = apiMessage;
                
                switch(msg.ms) {
                case apiMessageType.TEXT:
                    if ($tools.isShowEmojiIcon() && $emoji.isEmoji(msg.bo)) {
                        type = ppMessageType.EMOJI;
                    } else {
                        type = ppMessageType.TEXT;
                    }
                    break;
                    
                case apiMessageType.TXT:
                    type = ppMessageType.TEXT;
                    break;

                case apiMessageType.IMAGE:
                    type = ppMessageType.IMAGE;
                    break;

                case apiMessageType.FILE:
                    type = ppMessageType.FILE;
                    break;

                case apiMessageType.AUDIO:
                    type = ppMessageType.AUDIO;
                    break;
                }

                return type;
            },

            isAdmin = function(apiMessage) {
                return (apiMessage.fi != $user.getUser().getInfo().user_uuid) || apiMessage.tt == "S2P";
            },

            // services are all offline messages...
            msgByMachine = function(apiMessage) {
                return apiMessage.ft === Service.ApiMessage.TYPE_OG ||
                    apiMessage.ft === Service.ApiMessage.TYPE_AP;
            },

            innerCallback = function(ppMessageBuilder, success, callback) {

                var cb = function() {
                    if (callback) callback(ppMessageBuilder.build(), success);                    
                };
                
                // Async load user info
                if (isAdmin(apiMessage)) {

                    // msg generated by machine, not human
                    if (msgByMachine(apiMessage)) {
                        
                        ppMessageBuilder.userName(Service.Constants.i18n('SYSTEM_MSG'))
                            .userIcon(Service.Constants.ICON_DEFAULT_USER); // default server_name and user_icon

                        cb();
                        
                    } else {
                        var options = {
                            user_uuid: apiMessage.fi, // user_uuid
                            
                            user_fullname: apiMessage.from_user && apiMessage.from_user.user_fullname ?
                                apiMessage.from_user.user_fullname :
                                undefined, // user_name
                                
                            user_avatar: apiMessage.from_user && apiMessage.from_user.user_icon ?
                                $tools.getFileDownloadUrl(apiMessage.from_user.user_icon) :
                                undefined // user_avatar
                        };
                        
                        Service.$users.asyncGetUser(options, function(user) {
                            // get user info successfully !
                            if (user != null) {
                                // Update ppMessage body user info
                                ppMessageBuilder.userName(user.getInfo().user_fullname)
                                    .userIcon(user.getInfo().user_avatar);
                            } else {
                                ppMessageBuilder.userName(Service.Constants.i18n('DEFAULT_SERVE_NAME'))
                                    .userIcon(Service.Constants.ICON_DEFAULT_USER); // default server_name and user_icon
                            }

                            cb();
                        });    
                    }
                    
                } else {
                    cb();
                }
                
            },

            asyncBuildMessageData = function(ppMessageBuilder, callback) {
                var success = true;
                
                switch(apiMessage.ms) {
                case apiMessageType.TEXT:
                    if ($tools.isShowEmojiIcon() && $emoji.isEmoji(apiMessage.bo)) {
                        ppMessageBuilder.emojiMessageCode(apiMessage.bo);
                    } else {
                        ppMessageBuilder.textMessageBody(apiMessage.bo);
                    }
                    break;

                case apiMessageType.TXT:
                    $tools.getRemoteTextFileContent($json.parse(apiMessage.bo).fid, function(text) {
                        ppMessageBuilder.textMessageBody(text);
                        if (callback) callback(success);
                    }, function() {
                        success = false;
                        if (callback) callback(success);
                    });
                    return; // NOTE HERE: TXT message need async to get content

                case apiMessageType.IMAGE:
                    ppMessageBuilder.imageMessageUrl($tools.getFileDownloadUrl($json.parse(apiMessage.bo).orig));
                    break;

                case apiMessageType.FILE:
                    
                    var fileName = $json.parse(apiMessage.bo).name,
                    fileId = $json.parse(apiMessage.bo).fid,
                    fileUrl = $tools.getFileDownloadUrl(fileId, fileName),
                    fileServerUrl = fileUrl;

                    ppMessageBuilder.fileMessageLocalUrl(fileUrl)
                        .fileMessageName(fileName)
                        .fileMessageServerUrl(fileServerUrl);

                    break;

                case apiMessageType.AUDIO:
                    ppMessageBuilder.audio( $json.parse( apiMessage.bo ) );
                    break;

                default:
                    success = false;
                    break;
                }

                if (callback) callback(success);
            };

        this.asyncGetPPMessage = function(callback) {

            var ppMessageBuilder = new Service.PPMessage.Builder(getMessageType(apiMessage))
                .id(apiMessage.id)
                .timestamp(apiMessage.ts)
                .messageState( Service.PPMessage.STATE.FINISH )
                .conversationId(apiMessage.ci)
                .conversation({ uuid: apiMessage.ci })
                .rawData(apiMessage)
                .userId(apiMessage.fi)
                .admin(isAdmin(apiMessage));

            asyncBuildMessageData(ppMessageBuilder, function(success) {
                innerCallback(ppMessageBuilder, success, callback);
            });
        };
    }

    Service.ApiMessageAdapter = ApiMessageAdapter;
    
})(Service));
