/*
* 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.
*/

package org.apache.tomcat.buildutil;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.FileSet;

/**
 * Ant task that checks that all the files in the given fileset have end-of-line
 * delimiters that are appropriate for the current OS.
 *
 * <p>
 * The goal is to check whether we have problems with svn:eol-style property
 * when files are committed on one OS and then checked on another one.
 */
public class CheckEol extends Task {

    /** The files to be checked */
    private final List<FileSet> filesets = new LinkedList<>();

    /**
     * Sets the files to be checked
     *
     * @param fs The fileset to be checked.
     */
    public void addFileset( FileSet fs ) {
        filesets.add( fs );
    }

    /**
     * Perform the check
     *
     * @throws BuildException if an error occurs during execution of
     *    this task.
     */
    @Override
    public void execute() throws BuildException {

        Mode mode = null;
        if ("\n".equals(System.lineSeparator())) {
            mode = Mode.LF;
        } else if ("\r\n".equals(System.lineSeparator())) {
            mode = Mode.CRLF;
        } else {
            log("Line ends check skipped, because OS line ends setting is neither LF nor CRLF.",
                    Project.MSG_VERBOSE);
            return;
        }

        int count = 0;

        List<CheckFailure> errors = new ArrayList<>();

        // Step through each file and check.
        for (FileSet fs : filesets) {
            DirectoryScanner ds = fs.getDirectoryScanner(getProject());
            File basedir = ds.getBasedir();
            String[] files = ds.getIncludedFiles();
            if (files.length > 0) {
                log("Checking line ends in " + files.length + " file(s)");
                for (int i = 0; i < files.length; i++) {
                    File file = new File(basedir, files[i]);
                    log("Checking file '" + file + "' for correct line ends",
                            Project.MSG_DEBUG);
                    try {
                        check(file, errors, mode);
                    } catch (IOException e) {
                        throw new BuildException("Could not check file '"
                                + file.getAbsolutePath() + "'", e);
                    }
                    count++;
                }
            }
        }
        if (count > 0) {
            log("Done line ends check in " + count + " file(s), "
                    + errors.size() + " error(s) found.");
        }
        if (errors.size() > 0) {
            String message = "The following files have wrong line ends: "
                    + errors;
            // We need to explicitly write the message to the log, because
            // long BuildException messages may be trimmed. E.g. I observed
            // this problem with Eclipse IDE 3.7.
            log(message, Project.MSG_ERR);
            throw new BuildException(message);
        }
    }

    private enum Mode {
        LF, CRLF
    }

    private static class CheckFailure {
        private final File file;
        private final int line;
        private final String value;

        public CheckFailure(File file, int line, String value) {
            this.file = file;
            this.line = line;
            this.value = value;
        }

        @Override
        public String toString() {
            return System.lineSeparator() + file + ": uses " + value + " on line " + line;
        }
    }

    private void check(File file, List<CheckFailure> errors, Mode mode) throws IOException {
        try (FileInputStream fis = new FileInputStream(file);
                BufferedInputStream is = new BufferedInputStream(fis)) {
            int line = 1;
            int prev = -1;
            int ch;
            while ((ch = is.read()) != -1) {
                if (ch == '\n') {
                    if (mode == Mode.LF && prev == '\r') {
                        errors.add(new CheckFailure(file, line, "CRLF"));
                        return;
                    } else if (mode == Mode.CRLF && prev != '\r') {
                        errors.add(new CheckFailure(file, line, "LF"));
                        return;
                    }
                    line++;
                } else if (prev == '\r') {
                    errors.add(new CheckFailure(file, line, "CR"));
                    return;
                }
                prev = ch;
            }
        }
    }
}
