package public

//
// 消息入口
//

func DealMsgEnter(ip string,msgtype string,unmsg []byte) []byte {
	var ret interface{}
	switch msgtype{
	// 报告 消息
	case Msg_Report:
		var pmsg MJreport
		PntReport(string(unmsg))
		ParseJsonBody(unmsg,&pmsg)
		ret = pmsg.Msg_Deal()
		
	// 执行 消息
	case Msg_Exec:
		var pmsg MJexec
		PntExec(string(unmsg))
		ParseJsonBody(unmsg,&pmsg)
		ret = pmsg.Msg_Deal()
	
	// 备份 消息
	case Msg_Backup:
		var pmsg MJbackup
		PntBackup(string(unmsg))
		ParseJsonBody(unmsg,&pmsg)
		ret = pmsg.Msg_Deal()

	// 注册表 消息
	case Msg_Reg:
		var pmsg MJreg
		PntReg(string(unmsg))
		ParseJsonBody(unmsg,&pmsg)
		ret = pmsg.Msg_Deal()

	// 错误 消息
	case Msg_Error:
		PntError(string(unmsg))
		var pmsg MJerror
		ParseJsonBody(unmsg,&pmsg)
		ret = pmsg.Msg_Deal()
		return nil
	}
	
	return JsonToByte(&ret)
}



// 
// 具体消息实现
//

// 关于 report 报告 的 消息处理

func (rep *MJreport)Msg_Deal() interface{} {

	switch rep.Instruction{
				
	case Msg_Report_StartBak:
		return GJbackup(rep.Computername)

	case Msg_Report_OverBak:
		SysMsgBox(rep.Computername,`即将关机，如需取消关机,运行Z:\tools\【工具】取消关机.bat或在小工具-电源管理-取消自动关机`)
		return GJexecAck(Msg_Exec_TurnOffPC)

	case Msg_Report_WillTurnOffPC:
		rep.Reg_Write_Key_one_AC(
			Reg_Name_TurnOffTime,
			UnixTimeParse(&rep.Timestamp))
		rep.Reg_Write_Key_one_AC(
			Reg_Name_PowerStatus,
			Reg_Value_PowerStatus_OFF)
			
	case Msg_Report_WillTurnOnPC:
		rep.Reg_Write_Key_one_AC(
			Reg_Name_TurnOffTime,
			UnixTimeParse(&rep.Timestamp))
		rep.Reg_Write_Key_one_AC(
			Reg_Name_PowerStatus,
			Reg_Value_PowerStatus_ON)

	case Msg_Report_WillLogInUser:
		rep.Reg_Write_Key_one_AC(
			Reg_Name_LoginUserName,
			rep.Username)
		rep.Reg_Write_Key_one_AC(
			Reg_Name_LoginTime,
			UnixTimeParse(&rep.Timestamp))

	case Msg_Report_WillLogOutUser:
		rep.Reg_Write_Key_one_AC(
			Reg_Name_LogOffTime,
			UnixTimeParse(&rep.Timestamp))

		
	case Msg_Report_OverCopyToWeDrive:
		go func() {
			Delay(600)
			CopyStatusWeDrive[rep.Dept] = true
		}()

	default:
		PntOth("Default Report Json ",rep.Instruction)
	
	}
	return nil
}


// 关于 exec 执行 的 消息处理

func (exec *MJexec)Msg_Deal()interface{}{

	exec.IfDelay	= false

	switch exec.Instruction{
	case Msg_Exec_TurnOffPC:
		exec.Command 	= Msg_Exec_TurnOffPC_cmd
	
	case Msg_Exec_CancelTurnOffPC:
		exec.Command 	= Msg_Exec_CancelTurnOffPC_cmd

	case Msg_Exec_LogOffUser:
		exec.Command	= Msg_Exec_LogOffUser_cmd

	case Msg_Exec_RebootWindows:
		exec.Command	= Msg_Exec_RebootWindows_cmd

	}

	switch exec.Status{
	case Msg_Exec_State_Request:
		// maybe 当然时我来控制咯
		// 修改 请求状态，client daemon才可以执行
		switch exec.Instruction{
		case Msg_Exec_CopyWeDrive:
			if CopyStatusWeDrive[exec.Dept]{
				exec.Status = Msg_Exec_State_Ack
				CopyStatusWeDrive[exec.Dept] = false
			} else {
				return nil
			}
		}
		exec.Status = Msg_Exec_State_Ack
		return exec

	case Msg_Exec_State_Ack:
		// 进行延迟
		//if exec.IfDelay {Delay(&exec.Delay)}

		// 区分执行者
		switch exec.Cmder{
		case Msg_Exec_Cmder_ADServer:
			switch exec.Instruction{
			// 软件安装
			case Msg_Exec_InstallSoftware:
				// 对于 msi 格式
				// 从\\adserver安装
				// 共享则需要everyone的读取权限
				if HasSuffix(&exec.Command,".msi"){
					full_cmd := "msiexec /i " + SMB_ADSoftlike + `\` + exec.Command + " /qb"
					PsExec_sdi(exec.Computername,full_cmd,exec.SessionID)

				// 对于 exe 格式
				} else {
					// 如果文件存在，则执行C:\windows目录下的文件
					if exec.DataBool {
						PsExec_sdi(exec.Computername,Dir_Windows + exec.Command,exec.SessionID)
					// 如果文件不存在，从 ADMIN$ 复制到C:\windows，再执行
					} else {
						PsExec_sdic(exec.Computername,Dir_ADsoftware_local + exec.Command,exec.SessionID)
					}
				}
			}
		default:
			Execcmd_nowait(exec.Command)

		}
		switch exec.Instruction{
		case Msg_Exec_GUIExec:
			PsExec_sdi(exec.Computername,exec.Command,exec.SessionID)

			case Msg_Exec_CopyWeDrive:
				reg_Value_WeDriveDir := Reg_query_key_one(HKCU,Reg_Path_home,Reg_Name_WeDriveDir)
				cmd := `cmd /c xcopy ` + SMB_ADMainDeptShare + " /D " + reg_Value_WeDriveDir + `\` + Dir_dept_share + " /S /T /E /C /y"

				Execcmd_wait(cmd)
				SendServerReport(Msg_Report_OverCopyToWeDrive)
		}
	}
	return nil
}


// 关于 backup 备份 的 消息处理

func (bak * MJbackup)Msg_Deal() interface{}{

	switch bak.Status{

	case Msg_Backup_Status_Start:

		
		//bak.Username		= User_name
		bak.Computername 	= User_computername
		bak.Explain 		= "Backup Start"
		bak.Status 			= Msg_Backup_Status_If
		bak.Version			= BackupVersion
		bak.BatchFileName 	= Dir_DocuBase + bak.Version + bak.Username + BackupExtFile

		// maybe:收集D盘剩余空间
		PntReport(bak.Explain)

		//如果Start可以，并且得到了主用户

		//判断是否有最新版本的文件是否存在
		if NotExist(App_FreeFileSyncExe){
			SendServerError(Error_Null_App_Sync)
			return nil
		}

		//判断是否有最新版本的文件是否存在
		//C:\Users\Public\Documents\AD-Control\0416tengfei.ffs_batch
		if NotExist(bak.BatchFileName){
			bak.BatchFileExist		= false
		}else{
			bak.BatchFileExist		= true
		}
		SendServer(bak)
		return nil

	// 判断是否能进行备份
	case Msg_Backup_Status_If:
		
		bak.Username		= HostnameToUsername(&bak.Username)
		// 如果ffs的配置文件不存在 或者 是旧版本
		// 读取新文件
		if !bak.BatchFileExist || bak.Version != BackupVersion{
			bak.BatchFileData 	= CreateExtTempate(&bak.Username)
			bak.Version 		= BackupVersion
		}
		bak.Explain 		= "Backup Fill In BatchFile"
		bak.Status 			= Msg_Backup_Status_Continue
		// 交给daemon 处理 Msg_Backup_Status_Continue
		SendMsg(bak.Computername + DaemonListen,bak)
		return nil

	case Msg_Backup_Status_Continue:
		// 生成新FFS所使用的batch文件
		bak.BatchFileName 	= Dir_DocuBase + bak.Version + bak.Username + BackupExtFile
		if !bak.BatchFileExist{
			PntReport("init ",string(bak.BatchFileName))
			if err := WriteBytesFile(bak.BatchFileName,bak.BatchFileData);err !=nil{
				SendServerErrorf("%s %v-%v",bak.BatchFileName,Error_Fail_File_Write,err.Error())
			}
		}

		bak.Status 			= Msg_Backup_Status_Run
		bak.Explain		 	= "Backup Ready"
		return bak

	case Msg_Backup_Status_Run:
		SysMsgBox(bak.Computername,bak.Username + " 开始备份")
		PsExec_sd(bak.Computername,App_FreeFileSyncExe + " "+ bak.BatchFileName)
	}

	
	return nil
}


// 关于 registry 注册表 的 消息处理

func (reg * MJreg)Msg_Deal() interface{}{
	switch reg.Action{
	case Msg_Reg_Query:
			reg.DataStr = Reg_query_key_one(reg.Root,reg.Path,reg.Key)
		
	}
	return reg
}


// 关于 error 错误 的 消息处理

func (err * MJerror)Msg_Deal() interface{}{
	SendWX(err.Instruction)
	return nil
}