import org.codehaus.groovy.grails.plugins.springsecurity.Secured
import org.codehaus.groovy.grails.commons.*
import org.apache.commons.lang.WordUtils

/**
* Controller class for the application core views.
*/
class AppCoreController extends BaseController {

    def authService
    def assetService
    def appConfigService
    def createDataService
    def searchableService
    def assetSubItemService
    def createBulkDataService

    def index = { redirect(action:start,params:params) }

    // the delete, save and update actions only accept POST requests
    //def allowedMethods = [delete:'POST', save:'POST', update:'POST']

    /**
    * This is where we arrive after login.
    *  Attach the welcome flash message and redirect to where ever we want the user to start.
    * e.g. redirect(controller:"taskDetailed", action:"search")
    */
    def welcome = {
        def personInstance = authService.currentUser
        flash.message = "Welcome, ${personInstance.firstName} ${personInstance.lastName}."

        def sess = getSession()
        sess.setMaxInactiveInterval(personInstance.sessionTimeout)
        redirect(action:start)
    }

    /**
    * Render the start view.
    */
    def start = {
        def grailsVersion = grailsApplication.metadata['app.grails.version']
        def applicationVersion = grailsApplication.metadata['app.version']
        def applicationName = grailsApplication.metadata['app.name']
        def applicationVcsRevision = grailsApplication.metadata['app.vcsRevision']

        // Build the application string.
        def applicationString = WordUtils.capitalize(applicationName)
        if(applicationVersion)
            applicationString += "-" + applicationVersion
        if(applicationVcsRevision) {
            if(applicationVcsRevision.size() > 7)  { // Svn's $Rev: NUM $
                applicationVcsRevision = applicationVcsRevision[6..-3]
                applicationString += " (rev " + applicationVcsRevision + ")"
            }
            else
                applicationString += " (" + applicationVcsRevision + ")"
        }

        // Build the plugins string.
        def pluginProperties = grailsApplication.metadata.findAll {it.key.contains('plugin')}
        pluginProperties.each() {
            it.key = WordUtils.capitalize( (it.key + GString.EMPTY).split("\\.")[-1] )
        }
        pluginProperties = pluginProperties.sort { p1, p2 -> p1.key.compareToIgnoreCase(p2.key) }
        def plugins = pluginProperties.collect{ it.key + '-' + it.value }.join(", ")

        def sections = Section.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }

        return [grailsVersion: grailsVersion,
                    applicationString: applicationString,
                    plugins: plugins,
                    sections: sections]
    }

    /**
    * Allow a person to change their session timeout setting.
    */
    def changeSessionTimeout = {
        if (request.method == 'GET') {
            def personInstance = authService.currentUser
            return [ personInstance : personInstance ]       
        }
        if (request.method == 'POST') {
            def personInstance = authService.currentUser
                personInstance.properties = params
                if (!personInstance.hasErrors() && personInstance.save(flush: true)) {
                    def sess = getSession()
                    sess.setMaxInactiveInterval(personInstance.sessionTimeout)
                    flash.message = "Session timeout changed."
                    redirect(action:start)
                }
                else {
                    render(view:'changeSessionTimeout',model:[personInstance:personInstance])
                }
        }
    }

    /**
    * Allow a person to change their password.
    */
    def changePassword = {
        //def principal = authenticateService.principal()
        //log.info principal.getAuthorities()

        if (request.method == 'GET') {
            def personInstance = authService.currentUser
            return [ personInstance : personInstance ]       
        }

        if (request.method == 'POST') {
            def personInstance = authService.currentUser

            if(params.confirmPass == params.pass) {
                personInstance.pass = params.pass
                personInstance.password = authService.encodePassword(personInstance.pass)

                if (!personInstance.hasErrors() && personInstance.save(flush: true)) {
                    //userCache.removeUserFromCache(personInstance.loginName)
                    flash.message = "Password changed successfully."
                    redirect(action:start)
                }
                else {
                    render(view:'changePassword',model:[personInstance:personInstance])
                }
            }
            else {
                personInstance.errors.reject('person.pass.doesNotMatch',            // Error code, see grails-app/i18n/message.properties
                                                                ['pass', 'class Person'].toArray(),      // Groovy ListArray cast to Object[]
                                                                 '[NothingUseMessageProperites]')  // Default mapping string.
                render(view:'changePassword',model:[personInstance:personInstance])
            }

        }
    }

    /**
    * Render the manager view for manager or admin roles.
    */
    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_TaskManager',
                        'ROLE_InventoryManager', 'ROLE_AssetManager', 'ROLE_ProductionManager'])
    def manager = {
    }

    /**
    * Render the appAdmin view for admin roles.
    */
    @Secured(['ROLE_AppAdmin'])
    def appAdmin = {

        def offerBaseDataCreation = false
        def offerDemoDataCreation = false
        def baseDataCreated = appConfigService.exists("baseDataCreated")
        def demoDataCreated = appConfigService.exists("demoDataCreated")
        def demoDataCreationDisabled = appConfigService.exists("demoDataCreationDisabled")

        if(!baseDataCreated)
            offerBaseDataCreation = true

        if(baseDataCreated && !demoDataCreated && !demoDataCreationDisabled)
            offerDemoDataCreation = true

        return[baseDataCreated: baseDataCreated,
                        demoDataCreated: demoDataCreated,
                        offerDemoDataCreation: offerDemoDataCreation,
                        offerBaseDataCreation: offerBaseDataCreation,
                        demoDataCreationDisabled: demoDataCreationDisabled]
    }

    /**
    * Allow admin to disable demo data creation.
    */
    @Secured(['ROLE_AppAdmin'])
    def disableDemoDataCreation = {
        if(!appConfigService.set("demoDataCreationDisabled")) {
            flash.message = "Demo data creation could not be disabled."
            redirect(action: appAdmin)
            return
        }

        // Success.
        flash.message = "Demo data creation disabled."
        redirect(action: appAdmin)
    }

    /**
    * Allow admin to create base data.
    */
    @Secured(['ROLE_AppAdmin'])
    def createBaseData = {
        if(!createDataService.createBaseData()) {
            flash.message = "Base data could not be created."
            redirect(action: appAdmin)
            return
        }

        // Success.
        flash.message = "Base data created."
        redirect(action: appAdmin)
    }

    /**
    * Allow admin to create demo data.
    */
    @Secured(['ROLE_AppAdmin'])
    def createDemoData = {
        if(!createDataService.createDemoData()) {
            flash.message = "Demo data could not be created."
            redirect(action: appAdmin)
            return
        }

        // Success.
        flash.message = "Demo data created."
        redirect(action: appAdmin)
    }

    /**
    * Allow admin to create bulk test data.
    */
    @Secured(['ROLE_AppAdmin'])
    def createBulkTestData = {
        def result = createBulkDataService.createAll()
        if(!result.error) {
            flash.message = g.message(code:"default.create.success", args:["Bulk test data", ''])
            redirect(action: appAdmin)
            return
        }

        flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
        redirect(action: appAdmin)
    }

    /**
    * Allow admin to create bulk inventory test data.
    */
    @Secured(['ROLE_AppAdmin'])
    def createBulkInventoryTestData = {
        def result = createBulkDataService.createBulkInventoryTestData()
        if(!result.error) {
            flash.message = g.message(code:"default.create.success", args:["Bulk test data", ''])
            redirect(action: appAdmin)
            return
        }

        flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
        redirect(action: appAdmin)
    }

    /**
    * Render the application log file.
    */
    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_TaskManager',
                        'ROLE_InventoryManager', 'ROLE_AssetManager', 'ROLE_ProductionManager'])
    def appLog = {
        def file = new File(ConfigurationHolder.config.log4j.appenders.appLog.file)

        // Success.
        [log: file.text]
    }

    /**
    * Rebuild the text search index.
    */
    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_TaskManager',
                        'ROLE_InventoryManager', 'ROLE_AssetManager', 'ROLE_ProductionManager'])
    def rebuildTextSearchIndex = {
        InventoryIndexJob.triggerNow(['calledBy':'AppCoreController rebuildTextSearchIndex{}'])

        flash.message = g.message(code:"appCore.rebuild.text.search.index")
        redirect(action: manager)
    }

    /**
    * Allow admin to create recommended extended attributes for assets.
    */
    @Secured(['ROLE_AppAdmin'])
    def createRecommendedAssetExtendedAttributes = {
        def result = assetService.createRecommendedExtendedAttributes()
        if(!result.error) {
            flash.message = g.message(code:"default.create.success", args:["Extended attributes created", ''])
            redirect(action: appAdmin)
            return
        }

        flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
        redirect(action: appAdmin)
    }

    /**
    * Allow admin to create recommended extended attributes for level 1 assetSubItems.
    */
    @Secured(['ROLE_AppAdmin'])
    def createRecommendedAssetSubItemExtendedAttributes = {
        def result = assetSubItemService.createRecommendedExtendedAttributes()
        if(!result.error) {
            flash.message = g.message(code:"default.create.success", args:["Extended attributes created", ''])
            redirect(action: appAdmin)
            return
        }

        flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
        redirect(action: appAdmin)
    }

} // end of class.
