module.exports = function(grunt) {

    function cbk_dir_size(err, stdout, stderr, cb) {
        grunt.config.set('template.deb-control.options.data.package_size', stdout.trim());
        cb();
    }

    function version() {
        return '<%= meta.version_major %>.<%= meta.version_minor %>';
    }

    function deb_package_filename() {
        return '<%= meta.name %>_' + version() + '_<%= meta.architecture %>.deb';
    }

    function deb_package_latest_filename() {
        return '<%= meta.name %>_latest_<%= meta.architecture %>.deb';
    }

    // Project configuration.
    grunt.initConfig({

        pkg:  grunt.file.readJSON('package.json'),
        meta: grunt.file.readJSON('meta.json'),

        // Project paths to important directories
        project_paths: {
            'deploy_dir':  'deploy/',
            'package_dir': 'deploy/package/',
            'control_dir': 'deploy/ctrl/',
            'archive_dir': 'deploy/archive/'
        },
        // Paths related to DEB packages
        paths_deb: {
            'bin_dir': 'usr/local/bin/',
            'etc_dir': 'etc/mentat/',
            'lib_dir': 'usr/lib/python3/dist-packages/',
            'scr_dir': 'etc/mentat/scripts/',
            'man_dir': 'usr/share/man/'
        },

        // ---------------------------------------------------------------------
        // Cleanup various destinations
        clean: {
            // Cleanup package directory
            build: {
                src: [
                    "<%= project_paths.package_dir %>"
                ]
            }
        },

        // ---------------------------------------------------------------------
        // Running shel commands
        shell: {
            // Update NodeJS packages (Grunt, grunt plugins...)
            npm: {
                command: 'npm update'
            },
            // Calculate directory size
            dir_size: {
                command: '/usr/bin/du -k -s <%= project_paths.package_dir %> | /usr/bin/cut -f 1',
                options: {
                    callback: cbk_dir_size
                }
            },
            // Archive debian packages
            archive_deb: {
                command: 'mv -f <%= project_paths.deploy_dir %>*.deb <%= project_paths.archive_dir %>'
            },
            // Build debian package
            build_deb: {
                command: '/usr/bin/fakeroot /usr/bin/dpkg-deb --build <%= project_paths.package_dir %> <%= project_paths.deploy_dir %>' + deb_package_filename()
            },
            // Duplicate package from deb_package_filename() to deb_package_latest_filename()
            duplicate_deb: {
                command: 'cp -f <%= project_paths.deploy_dir %>' + deb_package_filename() + ' <%= project_paths.deploy_dir %>' + deb_package_latest_filename()
            },
            // FTP deployment
            ftp_deploy: {
                command: 'lftp -f .lftp'
            },
            // SCP deployment
            scp_deploy: {
                command: '/usr/bin/scp <%= project_paths.deploy_dir %>' + deb_package_filename() + ' <%= meta.pkg_server %>:<%= meta.pkg_location %>/stable'
            },
            // SCP deployment to devel server
            scp_deploy_dev: {
                command: '/usr/bin/scp <%= project_paths.deploy_dir %>' + deb_package_latest_filename() + ' <%= meta.dev_server %>:<%= meta.dev_location %>'
            },
            // DEB repo refresh
            repo_refresh: {
                command: '/usr/bin/ssh mach@<%= meta.pkg_server %> apt-update mentat'
            },
            // SSH install
            ssh_apt_update: {
                command: '/usr/bin/ssh root@<%= meta.dep_server %> aptitude update'
            },
            ssh_apt_upgrade: {
                command: '/usr/bin/ssh root@<%= meta.dep_server %> aptitude upgrade'
            },
            ssh_apt_install: {
                command: '/usr/bin/ssh root@<%= meta.dep_server %> aptitude install mentat-ng'
            },
            dpkg_install: {
                command: 'sudo dpkg -i <%= project_paths.deploy_dir %>' + deb_package_filename()
            },
            dpkg_install_dev: {
                command: '/usr/bin/ssh root@<%= meta.dev_server %> dpkg -i <%= meta.dev_location %>/' + deb_package_latest_filename()
            },
        },

        // ---------------------------------------------------------------------
        // Fill in certain template files
        template: {
            'deb-control': {
                'options': {
                    'data': {
                        'package_name': '<%= meta.name %>',
                        'package_version': version(),
                        'package_size': '0',
                        'architecture': '<%= meta.architecture %>'
                    }
                },
                'files': {
                    '<%= project_paths.package_dir %>DEBIAN/control': ['<%= project_paths.control_dir %>control.tmpl']
                }
            }
        },

        // ---------------------------------------------------------------------
        // Copy certain files to appropriate locations
        copy: {
            // Copy components for DEB package
            deb: {
                files: [
                    // ----- Copy binaries to package location
                    {
                        expand: true,
                        flatten: true,
                        cwd: 'bin/',
                        src: './mentat-*.py',
                        dest: '<%= project_paths.package_dir %><%= paths_deb.bin_dir %>'
                    },
                    // ----- Copy libraries to package location
                    {
                        expand: true,
                        cwd: 'lib/',
                        src: './**',
                        dest: '<%= project_paths.package_dir %><%= paths_deb.lib_dir %>'
                    },
                    // ----- Copy Debian package meta files to package location
                    {
                        src: '<%= project_paths.control_dir %>conffiles',
                        dest: '<%= project_paths.package_dir %>DEBIAN/conffiles'
                    },
                    {
                        src: '<%= project_paths.control_dir %>copyright',
                        dest: '<%= project_paths.package_dir %>DEBIAN/copyright'
                    },
                    {
                        src: '<%= project_paths.control_dir %>postinst',
                        dest: '<%= project_paths.package_dir %>DEBIAN/postinst'
                    },
                    // ----- Copy scripts to package location
                    {
                        expand: true,
                        cwd: 'scripts/',
                        src: './**',
                        dest: '<%= project_paths.package_dir %><%= paths_deb.scr_dir %>'
                    },
                    // ----- Copy configurations to package location
                    {
                        expand: true,
                        cwd: 'conf/',
                        src: './**',
                        dest: '<%= project_paths.package_dir %><%= paths_deb.etc_dir %>'
                    },
                    // ----- Copy additional files
                    {
                        expand: true,
                        flatten: true,
                        cwd: 'etc/',
                        src: './bash_mentat-ng-completion',
                        dest: '<%= project_paths.package_dir %>etc/bash_completion.d/'
                    },
                    {
                        expand: true,
                        flatten: true,
                        cwd: 'etc/',
                        src: './default_mentat',
                        dest: '<%= project_paths.package_dir %>etc/default/'
                    }
                ]
            }
        },

        // ---------------------------------------------------------------------
        // Make sure all files have necessary file permissions
        chmod: {
            options: {
                mode: '755'
            },
            deb_control: {
                // Target-specific file/dir lists and/or options go here.
                src: ['<%= project_paths.package_dir %>DEBIAN/postinst']
            },
            deb_bin: {
                // Target-specific file/dir lists and/or options go here.
                src: ['<%= project_paths.package_dir %><%= paths_deb.bin_dir %>/*']
            },
            deb_scr: {
                // Target-specific file/dir lists and/or options go here.
                src: ['<%= project_paths.package_dir %><%= paths_deb.scr_dir %>/*']
            }
        }

    });

    // ---------------------------------------------------------------------
    // Load grunt modules
    require('load-grunt-tasks')(grunt, { scope: 'devDependencies' });
    require('time-grunt')(grunt);

    grunt.registerTask('inc-version', function() {
        v = grunt.config.get('meta.version_minor');
        grunt.config.set('meta.version_minor', v + 1);
        console.log("Incremented version to: " + grunt.template.process(version()));
        grunt.config.set('template.deb-control.options.data.package_version', grunt.template.process(version()));
    });

    grunt.registerTask('save-meta', function() {
        try {
            obj = JSON.parse(JSON.stringify(grunt.config.get('meta')));
        } catch (e){
            grunt.log.error(e);
            grunt.fail.warn("Error parsing the JSON data.", 3);
        }
        grunt.file.write('meta.json', JSON.stringify(obj, null, 4));
    });

    // ---------------------------------------------------------------------
    // Setup custom task(s).
    grunt.registerTask('deb-build', ['clean:build', 'shell:archive_deb', 'copy:deb', 'chmod', 'shell:dir_size', 'inc-version', 'save-meta', 'template:deb-control', 'shell:build_deb', 'clean:build', 'shell:duplicate_deb']);
    //grunt.registerTask('scp-deploy', ['shell:scp_deploy', 'shell:repo_refresh', 'shell:ssh_apt_update', 'shell:ssh_apt_install']);
    grunt.registerTask('scp-deploy', ['shell:scp_deploy', 'shell:scp_deploy_dev', 'shell:repo_refresh']);
    grunt.registerTask('deb-deploy', ['deb-build', 'scp-deploy', 'shell:dpkg_install_dev', 'shell:dpkg_install']);
    grunt.registerTask('deb-local-deploy', ['deb-build', 'shell:dpkg_install']);
    grunt.registerTask('update', ['shell:npm']);
    grunt.registerTask('default',  ['build-app']);
};