class TaskService {

    boolean transactional = false

    def dateUtilService
    def authenticateService

    def create(params) {
        Task.withTransaction { status ->
            def result = [:]
            // Default status to "not started" if not supplied.
            params.taskStatus = params.taskStatus ?: TaskStatus.get(1)
            def taskInstance = new Task(params)
            result.taskInstance = taskInstance

            // Get person in a safe way to avoid a null userDomain during bootstrap.
            def userDomain = authenticateService.userDomain()
            def person = userDomain ? Person.get(userDomain.id) : Person.get(1)

            if(taskInstance.save()) {
                def taskModification = new TaskModification(person:person,
                                                        taskModificationType: TaskModificationType.get(1),
                                                        task: taskInstance)

                if(!taskModification.save()) {
                    status.setRollbackOnly()
                    taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
                    result.error = true
                    return result
                }

                return result
            }
            else {
                result.error = true
                return result
            }

        } //end withTransaction
    } // end create()

    def start() {
        //TaskModificationType.get(2)
    }  // end start()

    def update(params) {
        Task.withTransaction { status ->
            def result = [:]
            result.taskInstance = Task.get(params.id)
            if(result.taskInstance) {

                // Optimistic locking check.
                if(params.version) {
                    def version = params.version.toLong()
                    if(result.taskInstance.version > version) {
                        status.setRollbackOnly()
                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
                        result.error = true
                        return result
                    }
                }

                result.taskInstance.properties = params

                if(result.taskInstance.save()) {
                    def taskModification = new TaskModification(person:Person.get(authenticateService.userDomain().id),
                                                            taskModificationType: TaskModificationType.get(3),
                                                            task: result.taskInstance)
                    if(taskModification.save()) {
                        // All went well.
                        return result
                    }
                    else {
                        status.setRollbackOnly()
                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
                        result.error = true
                        return result
                    }
                }
            }
            // Something failed.
            status.setRollbackOnly()
            result.error = true
            return result

        } //end withTransaction
    }  // end update()

    def complete(params) {
        Task.withTransaction { status ->
            def result = [:]
            result.taskInstance = Task.get(params.id)
            if(result.taskInstance) {

                // Optimistic locking check.
                if(params.version) {
                    def version = params.version.toLong()
                    if(result.taskInstance.version > version) {
                        status.setRollbackOnly()
                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
                        result.error = true
                        return result
                    }
                }

                result.taskInstance.taskStatus = TaskStatus.get(3)

                if(result.taskInstance.save()) {
                    def taskModification = new TaskModification(person:Person.get(authenticateService.userDomain().id),
                                                            taskModificationType: TaskModificationType.get(4),
                                                            task: result.taskInstance)
                    if(taskModification.save()) {
                        // All went well.
                        return result
                    }
                    else {
                        status.setRollbackOnly()
                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
                        result.error = true
                        return result
                    }
                }
            }
            // Something failed.
            status.setRollbackOnly()
            result.error = true
            return result

        } //end withTransaction
    }  // end complete()

    def reopen(params) {
        Task.withTransaction { status ->
            def result = [:]
            result.taskInstance = Task.get(params.id)
            if(result.taskInstance) {

                // Optimistic locking check.
                if(params.version) {
                    def version = params.version.toLong()
                    if(result.taskInstance.version > version) {
                        status.setRollbackOnly()
                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
                        result.error = true
                        return result
                    }
                }

                result.taskInstance.taskStatus = TaskStatus.get(2)

                if(result.taskInstance.save()) {
                    def taskModification = new TaskModification(person:Person.get(authenticateService.userDomain().id),
                                                            taskModificationType: TaskModificationType.get(5),
                                                            task: result.taskInstance)
                    if(taskModification.save()) {
                        // All went well.
                        return result
                    }
                    else {
                        status.setRollbackOnly()
                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
                        result.error = true
                        return result
                    }
                }
            }
            // Something failed.
            status.setRollbackOnly()
            result.error = true
            return result

        } //end withTransaction
    }  // end reopen()

    def trash(params) {
        Task.withTransaction { status ->
            def result = [:]
            result.taskInstance = Task.get(params.id)
            if(result.taskInstance) {

                // Optimistic locking check.
                if(params.version) {
                    def version = params.version.toLong()
                    if(result.taskInstance.version > version) {
                        status.setRollbackOnly()
                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
                        result.error = true
                        return result
                    }
                }

                result.taskInstance.trash = true

                if(result.taskInstance.save()) {
                    def taskModification = new TaskModification(person:Person.get(authenticateService.userDomain().id),
                                                            taskModificationType: TaskModificationType.get(6),
                                                            task: result.taskInstance)
                    if(taskModification.save()) {
                        // All went well.
                        return result
                    }
                    else {
                        status.setRollbackOnly()
                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
                        result.error = true
                        return result
                    }
                }
            }
            // Something failed.
            status.setRollbackOnly()
            result.error = true
            return result

        } //end withTransaction
    }  // end trash()

    def restore(params) {
        Task.withTransaction { status ->
            def result = [:]
            result.taskInstance = Task.get(params.id)
            if(result.taskInstance) {

                // Optimistic locking check.
                if(params.version) {
                    def version = params.version.toLong()
                    if(result.taskInstance.version > version) {
                        status.setRollbackOnly()
                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
                        result.error = true
                        return result
                    }
                }

                result.taskInstance.trash = false

                if(result.taskInstance.save()) {
                    def taskModification = new TaskModification(person:Person.get(authenticateService.userDomain().id),
                                                            taskModificationType: TaskModificationType.get(7),
                                                            task: result.taskInstance)
                    if(taskModification.save()) {
                        // All went well.
                        return result
                    }
                    else {
                        status.setRollbackOnly()
                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
                        result.error = true
                        return result
                    }
                }
            }
            // Something failed.
            status.setRollbackOnly()
            result.error = true
            return result

        } //end withTransaction
    }  // end restore()

    def approve(params) {
        Task.withTransaction { status ->
            def result = [:]
            result.taskInstance = Task.get(params.id)
            if(result.taskInstance) {

                // Optimistic locking check.
                if(params.version) {
                    def version = params.version.toLong()
                    if(result.taskInstance.version > version) {
                        status.setRollbackOnly()
                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
                        result.error = true
                        return result
                    }
                }

                result.taskInstance.approved = true

                if(result.taskInstance.save()) {
                    def taskModification = new TaskModification(person:Person.get(authenticateService.userDomain().id),
                                                            taskModificationType: TaskModificationType.get(8),
                                                            task: result.taskInstance)
                    if(taskModification.save()) {
                        // All went well.
                        return result
                    }
                    else {
                        status.setRollbackOnly()
                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
                        result.error = true
                        return result
                    }
                }
            }
            // Something failed.
            status.setRollbackOnly()
            result.error = true
            return result

        } //end withTransaction
    }  // end approve()

    def renegeApproval(params) {
        Task.withTransaction { status ->
            def result = [:]
            result.taskInstance = Task.get(params.id)
            if(result.taskInstance) {

                // Optimistic locking check.
                if(params.version) {
                    def version = params.version.toLong()
                    if(result.taskInstance.version > version) {
                        status.setRollbackOnly()
                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
                        result.error = true
                        return result
                    }
                }

                result.taskInstance.approved = false

                if(result.taskInstance.save()) {
                    def taskModification = new TaskModification(person:Person.get(authenticateService.userDomain().id),
                                                            taskModificationType: TaskModificationType.get(9),
                                                            task: result.taskInstance)
                    if(taskModification.save()) {
                        // All went well.
                        return result
                    }
                    else {
                        status.setRollbackOnly()
                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
                        result.error = true
                        return result
                    }
                }
            }
            // Something failed.
            status.setRollbackOnly()
            result.error = true
            return result

        } //end withTransaction
    }  // end renegeApproval()

} // end TaskService
