'use strict';

/**
 * Requirements
 * @ignore
 */
const BaseCommand = require('./BaseCommand.js').BaseCommand;
const CompileSassTask = require('../task/CompileSassTask.js').CompileSassTask;
const PostprocessCssTask = require('../task/PostprocessCssTask.js').PostprocessCssTask;
const WriteFilesTask = require('../task/WriteFilesTask.js').WriteFilesTask;
const PathesConfiguration = require('../model/configuration/PathesConfiguration.js').PathesConfiguration;
const BuildConfiguration = require('../model/configuration/BuildConfiguration.js').BuildConfiguration;
const ModelSynchronizer = require('../watch/ModelSynchronizer.js').ModelSynchronizer;
const CliLogger = require('../cli/CliLogger.js').CliLogger;
const Context = require('../application/Context.js').Context;
const co = require('co');


/**
 * @memberOf command
 */
class SassCommand extends BaseCommand
{
    /**
     */
    constructor(context)
    {
        super(context);

        // Assign options
        this._name = ['sass'];
    }


    /**
     * @inheritDoc
     */
    static get injections()
    {
        return { 'parameters': [Context] };
    }


    /**
     * @inheritDocs
     */
    static get className()
    {
        return 'command/SassCommand';
    }


    /**
     * @inheritDocs
     */
    get help()
    {
        const help =
        {
            name: this._name,
            description: 'Compiles and optimizes css files',
            actions:
            [
                {
                    name: 'compile [query]',
                    description: 'Compiles all scss files',
                    options:
                    [
                        {
                            name: 'query',
                            type: 'optional',
                            defaultValue: '*',
                            description: 'Compiles scss for the given site'
                        }
                    ]
                },
                {
                    name: 'watch',
                    description: 'Watches for changes and compiles scss files when necessary'
                }
            ]
        };
        return help;
    }


    /**
     * @inheritDocs
     * @returns {Promise}
     */
    compile(parameters)
    {
        const scope = this;
        const promise = co(function *()
        {
            const logger = scope.createLogger('command.sass.compile');
            const pathesConfiguration = scope.context.di.create(PathesConfiguration);
            const buildConfiguration = scope.context.di.create(BuildConfiguration);
            const path = yield pathesConfiguration.resolveCache('/css');
            const options =
            {
                query: parameters && parameters._[0] || '*',
                writePath: path
            }
            const mapping = new Map();
            mapping.set(CliLogger, logger);
            yield scope.context.di.create(CompileSassTask, mapping)
                .pipe(scope.context.di.create(PostprocessCssTask, mapping))
                .pipe(scope.context.di.create(WriteFilesTask, mapping))
                .run(buildConfiguration, options);
        });
        return promise;
    }


    /**
     * @inheritDocs
     * @returns {Promise}
     */
    watch(parameters)
    {
        const scope = this;
        const promise = co(function *()
        {
            const logger = scope.createLogger('command.sass.watch');
            const modelSynchronizer = scope.context.di.create(ModelSynchronizer);
            yield scope.compile(parameters);
            yield modelSynchronizer.start();
            modelSynchronizer.signals.invalidated.add((synchronizer, invalidations) =>
            {
                if (invalidations.extensions.indexOf('.scss') > -1)
                {
                    logger.info('Detected change in <Sass Files>');
                    scope.compile(parameters);
                }
            });
        });
        return promise;
    }


    /**
     * @inheritDocs
     * @returns {Promise<Server>}
     */
    doExecute(parameters)
    {
        if (parameters.action === 'watch')
        {
            return this.watch(parameters);
        }
        return this.compile(parameters);
    }
}


/**
 * Exports
 * @ignore
 */
module.exports.SassCommand = SassCommand;

@@ -343,24 +343,94 @@
 eFilesTask;%0A
+const DecorateTask = require('../task/DecorateTask.js').DecorateTask;%0A
 const Pathes
@@ -2834,16 +2834,93 @@
 th: path
+,%0A                decoratePrepend: '/** generated ' + (new Date()) + ' **/%5Cn'
 %0A       
@@ -2917,32 +2917,33 @@
 n'%0A            %7D
+;
 %0A            con
@@ -3146,32 +3146,102 @@
 Task, mapping))%0A
+                .pipe(scope.context.di.create(DecorateTask, mapping))%0A
                 

add timestamp to generated css