import { SDKLog } from "../../../util/SDKLog";
import { CastSessionVO } from "../../../vo/cast/CastSessionVO";
import { ScreenOrientation } from "../../../vo/report/ScreenOrientation";
import { ControllerDeviceVO } from "../../../vo/device/ControllerDeviceVO";
import { CastSlot } from "../../../vo/report/CastSlot";
import { JsonParser } from "../../json/JsonParser";
import { AccountBindDeviceMessage } from "../message/AccountBindDeviceMessage";
import { CastSessionMessage } from "../message/CastSessionMessage";
import { DataMessage } from "../message/DataMessage";
import { DisplayReportMessage } from "../message/DisplayReportMessage";
import { MsgType } from "../message/MsgType";
import { SessionDestroyReason } from "../message/SessionDestroyReason";
import { UserHasBeenKickedMessage } from "../message/UserHasBeenKickedMessage";
import { WillMessage } from "../message/WillMessage";
import { YMSMessage } from '../message/YMSMessage';

export class MessageParser {
    private readonly TAG: string = "MessageParser";
    private readonly jsonParser: JsonParser;

    constructor() {
        this.jsonParser = new JsonParser();
    }

    public parse(message: string): YMSMessage {
        let temp: any = this.jsonParser.fromJson(message);
        let result: any;

        if (MsgType.WILL === temp?.msgType) {
            SDKLog.i(this.TAG, "parse will message");
            result = new WillMessage(temp!.sender, temp!.receiver);
            result.timestamp = temp?.timestamp;
            result.senderClientId = temp?.senderClientId;

        } else if (MsgType.REPORT === temp?.msgType) {
            SDKLog.i(this.TAG, "parse displayReport message");
            result = new DisplayReportMessage();
            result.timestamp = temp?.timestamp;
            result.senderClientId = temp?.senderClientId;
            // displayDevice
            result.displayReport.displayDevice.displayCode = temp?.displayReport.displayDevice.displayCode;
            result.displayReport.displayDevice.displayDeviceId = temp?.displayReport.displayDevice.displayDeviceId;
            result.displayReport.displayDevice.displayDeviceName = temp?.displayReport.displayDevice.displayDeviceName;
            result.displayReport.displayDevice.gateway = temp?.displayReport.displayDevice.gateway;
            result.displayReport.displayDevice.ip = temp?.displayReport.displayDevice.ip;
            result.displayReport.displayDevice.mask = temp?.displayReport.displayDevice.mask;
            result.displayReport.displayDevice.outIp = temp?.displayReport.displayDevice.outIp;
            // displaySupport
            result.displayReport.displaySupport.isSupportMirrorToDisplay = temp?.displayReport.displaySupport.isSupportMirrorToDisplay;
            result.displayReport.displaySupport.isSupportMirrorToController = temp?.displayReport.displaySupport.isSupportMirrorToController;
            result.displayReport.displaySupport.isSupportDisplayRemote = temp?.displayReport.displaySupport.isSupportDisplayRemote;
            result.displayReport.displaySupport.isSupportDisplayScreenCapture = temp?.displayReport.displaySupport.isSupportDisplayScreenCapture;
            result.displayReport.displaySupport.isSupportDisplayAppInstall = temp?.displayReport.displaySupport.isSupportDisplayAppInstall;
            result.displayReport.displaySupport.isSupportShareImageToDisplay = temp?.displayReport.displaySupport.isSupportShareImageToDisplay;
            result.displayReport.displaySupport.isSupportShareVideoToDisplay = temp?.displayReport.displaySupport.isSupportShareVideoToDisplay;
            result.displayReport.displaySupport.isSupportShareDocumentToDisplay = temp?.displayReport.displaySupport.isSupportShareDocumentToDisplay;
            result.displayReport.displaySupport.majorVersion = temp?.displayReport.displaySupport.majorVersion;
            result.displayReport.displaySupport.minorVersion = temp?.displayReport.displaySupport.minorVersion;
            // displayReport
            result.displayReport.castSlots = temp?.displayReport.castSlots.map((slot:any) => 
                    new CastSlot(slot.castType, slot.used, slot.max));
            result.displayReport.isCastEnable = temp?.displayReport.isCastEnable;
            result.displayReport.isCastExclusive = temp?.displayReport.isCastExclusive;
            // isDisplayDeviceOnline 是后增字段，可能在已有的消息/http中不存在
            if (temp?.displayReport.isDisplayDeviceOnline !== undefined) {
                result.displayReport.isDisplayDeviceOnline = temp?.displayReport.isDisplayDeviceOnline;
            } else {
                result.displayReport.isDisplayDeviceOnline = true;
            };
            // screenOrientation 是后增字段，可能在已有的消息/http中不存在
            if (temp?.displayReport.screenOrientation !== undefined) {
                result.displayReport.screenOrientation = temp?.displayReport.screenOrientation;
            } else {
                result.displayReport.screenOrientation = ScreenOrientation.LANDSCAPE;
            };

        } else if (MsgType.DATA === temp?.msgType) {
            SDKLog.i(this.TAG, "parse data message");
            result = new DataMessage();
            result.timestamp = temp?.timestamp;
            result.senderClientId = temp?.senderClientId;
            result.data = temp?.data;

        } else if (MsgType.CAST === temp?.msgType) {
            SDKLog.i(this.TAG, "parse cast message");
            result = new CastSessionMessage(temp?.sender, temp?.receiver);
            result.timestamp = temp?.timestamp;
            result.senderClientId = temp?.senderClientId;
            // CastSessionVO
            result.castSession = new CastSessionVO();
            result.castSession.castSessionId = temp?.castSession.castSessionId;
            result.castSession.guid = temp?.castSession.guid;
            result.castSession.displayCode = temp?.castSession.displayCode;
            result.castSession.castType = temp?.castSession.castType;
            result.castSession.castProtocol = temp?.castSession.castProtocol;
            // ControllerDeviceVO 是后增字段，可能在已有的消息/http中不存在
            if (temp?.castSession.controllerDevice !== undefined) {
                result.castSession.controllerDevice.guid = temp?.castSession.controllerDevice.guid;
                result.castSession.controllerDevice.controllerDeviceType = temp?.castSession.controllerDevice.controllerDeviceType;
                result.castSession.controllerDevice.ip = temp?.castSession.controllerDevice.ip;
                result.castSession.controllerDevice.gateway = temp?.castSession.controllerDevice.gateway;
                result.castSession.controllerDevice.mask = temp?.castSession.controllerDevice.mask;
                result.castSession.controllerDevice.outIp = temp?.castSession.controllerDevice.outIp;
            } else {
                result.castSession.controllerDevice = new ControllerDeviceVO();
            };

            result.action = temp?.action;
            result.mediaPayload = temp?.mediaPayload;
            // SessionDestroyReason 是后增字段，可能在已有的消息/http中不存在
            if (temp?.destroyReason !== undefined) {
                result.destroyReason = temp?.destroyReason;
            } else {
                result.destroyReason = SessionDestroyReason.NONE;
            }

        } else if (MsgType.ACCOUNT === temp?.msgType) {
            SDKLog.i(this.TAG, "parse account message");
            result = new UserHasBeenKickedMessage();
            result.timestamp = temp?.timestamp;
            result.senderClientId = temp?.senderClientId;
            // accountInfo
            result.user.accessToken = temp?.user.accessToken;
            result.user.controllerDeviceType = temp?.user.controllerDeviceType;
            result.user.guid = temp?.user.guid;
            result.user.loginTime = temp?.user.loginTime;
            result.user.userId = temp?.user.userId;
            result.user.account.accountId = temp?.user.account.accountId;
            result.user.account.phoneNumber = temp?.user.account.phoneNumber;
            result.user.account.registerTime = temp?.user.account.registerTime;
            result.user.account.vipLevel = temp?.user.account.vipLevel;

        } else if (MsgType.BIND_DEVICE === temp?.msgType) {
            SDKLog.i(this.TAG, "parse bind device message");
            result = new AccountBindDeviceMessage();
            result.timestamp = temp?.timestamp;
            result.senderClientId = temp?.senderClientId;
            // bindDeviceInfo
            result.bindDeviceAction = temp?.bindDeviceAction;
            result.accountBindDevice.accountId = temp?.accountBindDevice.accountId;
            result.accountBindDevice.displayDeviceAlias = temp?.accountBindDevice.displayDeviceAlias;
            result.accountBindDevice.displayDevice.displayCode = temp?.accountBindDevice.displayDevice.displayCode;
            result.accountBindDevice.displayDevice.displayDeviceId = temp?.accountBindDevice.displayDevice.displayDeviceId;
            result.accountBindDevice.displayDevice.displayDeviceName = temp?.accountBindDevice.displayDevice.displayDeviceName;
            result.accountBindDevice.displayDevice.gateway = temp?.accountBindDevice.displayDevice.gateway;
            result.accountBindDevice.displayDevice.ip = temp?.accountBindDevice.displayDevice.ip;
            result.accountBindDevice.displayDevice.mask = temp?.accountBindDevice.displayDevice.mask;
            result.accountBindDevice.displayDevice.outIp = temp?.accountBindDevice.displayDevice.outIp;
        }
        SDKLog.i(this.TAG, "parse message end, msg = " + result?.toString());
        return result;
    }

    public toJson(message: YMSMessage): string {
        let ret: string = "";
        if (null !== message) {
            ret = this.jsonParser.toJson(message);
        }
        SDKLog.i(this.TAG, "toJson = " + ret);
        return ret;
    }
}
