// GetSchedule returns a task schedule
func GetSchedule(w rest.ResponseWriter, r *rest.Request) {
	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), 400)
		return

	}
	defer dbConn.Close()
	err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-read")
	if err != nil {
		logit.Error.Println("validate token error " + err.Error())
		rest.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}
	ID := r.PathParam("ID")

	if ID == "" {
		rest.Error(w, "ID required", 400)
		return
	}

	result, err := task.GetSchedule(dbConn, ID)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), 400)
		return
	}
	//logit.Info.Println("GetSchedule api returns serverip of " + result.Serverip)

	w.WriteJson(result)

}
// ExecuteNow executes a task schedule on demand allowing an immediate task execution
func ExecuteNow(w rest.ResponseWriter, r *rest.Request) {

	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), 400)
		return

	}
	defer dbConn.Close()
	postMsg := BackupNowPost{}
	err = r.DecodeJsonPayload(&postMsg)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	err = secimpl.Authorize(dbConn, postMsg.Token, "perm-backup")
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	if postMsg.ProfileName == "" {
		logit.Error.Println("node ProfileName required")
		rest.Error(w, "ProfileName required", 400)
		return
	}

	if postMsg.ScheduleID == "" {
		logit.Error.Println("schedule ID required")
		rest.Error(w, "schedule ID required", 400)
		return
	}

	schedule, err2 := task.GetSchedule(dbConn, postMsg.ScheduleID)
	if err2 != nil {
		logit.Error.Println(err2.Error())
		rest.Error(w, err2.Error(), 400)
		return
	}

	request := task.TaskRequest{}
	request.ScheduleID = postMsg.ScheduleID

	//in the case of a restore job, the user can supply a new containername
	if postMsg.ContainerName == "" {
		request.ContainerName = schedule.ContainerName
	} else {
		request.ContainerName = postMsg.ContainerName
	}

	//the restore command requires the task schedule statusID
	request.StatusID = postMsg.StatusID

	request.ProfileName = postMsg.ProfileName

	//for restore jobs, we go ahead and create the new
	//database container here, could possible move to the
	//restore job task later on
	if postMsg.ProfileName == "restore" {
		var newid string
		provisionParams := swarmapi.DockerRunRequest{}
		provisionParams.Profile = "SM"
		provisionParams.ProjectID = postMsg.ProjectID
		provisionParams.ContainerName = postMsg.ContainerName
		provisionParams.Image = "cpm-node"
		provisionParams.IPAddress = schedule.Serverip
		//logit.Info.Println("before restore provision with...")
		//logit.Info.Println("profile=" + provisionParams.Profile)
		//logit.Info.Println("projectid=" + provisionParams.ProjectID)
		//logit.Info.Println("containername=" + provisionParams.ContainerName)
		//logit.Info.Println("image=" + provisionParams.Image)
		//logit.Info.Println("ipaddress=" + provisionParams.IPAddress)
		newid, err = provisionImpl(dbConn, &provisionParams, false)
		if err != nil {
			logit.Error.Println(err.Error())
			rest.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		logit.Info.Printf("created node for restore job id = " + newid)
	}

	output, err := task.ExecuteNowClient(&request)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	logit.Info.Println("output=" + output.Output)

	w.WriteHeader(http.StatusOK)
	status := types.SimpleStatus{}
	status.Status = "OK"
	w.WriteJson(&status)
}
// DeleteTaskStatus deletes a task status and any related backup files
func DeleteTaskStatus(w rest.ResponseWriter, r *rest.Request) {
	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), 400)
		return

	}
	defer dbConn.Close()

	postMsg := DeleteStatusPost{}
	err = r.DecodeJsonPayload(&postMsg)
	if err != nil {
		logit.Error.Println("decode" + err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	err = secimpl.Authorize(dbConn, postMsg.Token, "perm-backup")
	if err != nil {
		logit.Error.Println("validate token error " + err.Error())
		rest.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	taskstatus, err := task.GetStatus(dbConn, postMsg.StatusID)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	var schedule task.TaskSchedule
	schedule, err = task.GetSchedule(dbConn, taskstatus.ScheduleID)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	//delete any backup files if necessary
	if taskstatus.ProfileName == "pg_basebackup" {
		deletereq := cpmserverapi.DiskDeleteRequest{}
		deletereq.Path = taskstatus.Path
		var deleteresp cpmserverapi.DiskDeleteResponse
		deleteresp, err = cpmserverapi.DiskDeleteClient(schedule.Serverip, &deletereq)
		if err != nil {
			logit.Error.Println(err.Error())
			rest.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		if deleteresp.Status != "OK" {
			logit.Error.Println("Status not OK in deletevolume " + deleteresp.Status)
			rest.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	}

	err = task.DeleteStatus(dbConn, postMsg.StatusID)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}