/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
*/
var processWhiteSpace = require('./lib/process-white-space');
var fs = require('fs');

module.exports = function(grunt) {

    grunt.registerTask('whitespace-check', 'Check for whitespace issues.', function() {
        var done = this.async();
        var complainedAboutWhitespace = false;
        processWhiteSpace(function(file, newSource) {
            if (!complainedAboutWhitespace) {
                grunt.log.writeln("files with whitespace issues: (to fix: `grunt whitespace-fix`)");
                complainedAboutWhitespace = true;
            }
            grunt.log.writeln("   " + file);
        }, done);
    });
    
    grunt.registerTask('whitespace-fix', 'Convert tabs to four spaces, eliminate trailing whitespace, convert newlines to proper form.', function() {
        var done = this.async();
        var complainedAboutWhitespace = false;
        processWhiteSpace(function(file, newSource) {
            if (!complainedAboutWhitespace) {
                grunt.log.writeln("Fixed whitespace issues in:");
                complainedAboutWhitespace = true;
            }
            fs.writeFileSync(file, newSource, 'utf8');
            grunt.log.writeln("   " + file);
        }, done);
    });
}
