/*
 * 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.creadur.tentacles;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.codehaus.swizzle.stream.DelimitedTokenReplacementInputStream;
import org.codehaus.swizzle.stream.ExcludeFilterInputStream;
import org.codehaus.swizzle.stream.StringTokenHandler;

/**
 * Little utility that will yank the author comments from java files.
 * 
 * If the resulting comment block is effectively empty, it will be yanked too.
 */
public class Deauthorize {

    /**
     * All input must be valid directories.
     * 
     * Invalid input is logged to System.err and skipped
     * 
     * @param args
     *            a list of directories to scan and fix
     * @throws Exception
     */
    public static void main(final String[] args) throws Exception {

        if (args.length == 0) {
            throw new IllegalArgumentException(
                    "At least one directory must be specified");
        }

        final List<File> dirs = new ArrayList<File>();

        // Check the input args upfront
        for (final String arg : args) {
            final File dir = new File(arg);

            if (not(dir.exists(), "Does not exist: %s", arg)) {
                continue;
            }
            if (not(dir.isDirectory(), "Not a directory: %s", arg)) {
                continue;
            }

            dirs.add(dir);
        }

        // Exit if we got bad input
        if (dirs.size() != args.length) {
            System.exit(1);
        }

        // Go!
        for (final File dir : dirs) {
            deauthorize(dir);
        }
    }

    /**
     * Iterate over all the java files in the given directory
     * 
     * Read in the file so we can guess the line ending -- if we didn't need to
     * do that we could just stream. Run the content through Swizzle Stream and
     * filter out any author tags as well as any comment blocks that wind up (or
     * already were) empty as a result.
     * 
     * If that had any effect on the contents of the file, write it back out.
     * 
     * Should skip any files that are not readable or writable.
     * 
     * Will log an error on System.err for any files that were updated and were
     * not writable. Files that are not writable and don't need updating are
     * simply ignored.
     * 
     * @param dir
     * @throws IOException
     */
    private static void deauthorize(final File dir) throws IOException {
        deauthorize(dir, new IOSystem());
    }

    private static void deauthorize(final File dir, final IOSystem io)
            throws IOException {
        for (final File file : new FileSystem().collect(dir, ".*\\.java")) {

            if (not(file.canRead(), "File not readable: %s",
                    file.getAbsolutePath())) {
                continue;
            }

            final String text = io.slurp(file);

            // You really can't trust text to be in the native line ending
            final String eol = (text.contains("\r\n")) ? "\r\n" : "\n";
            final String startComment = eol + "/*";
            final String endComment = "*/" + eol;

            InputStream in = new ByteArrayInputStream(text.getBytes());

            // Yank author tags
            in = new ExcludeFilterInputStream(in, " * @author", eol);

            // Clean "empty" comments
            in =
                    new DelimitedTokenReplacementInputStream(in, startComment,
                            endComment, new StringTokenHandler() {
                                @Override
                                public String handleToken(
                                        final String commentBlock)
                                        throws IOException {

                                    // Yank if empty
                                    if (commentBlock.replaceAll("[\\s*]", "")
                                            .length() == 0) {
                                        return eol;
                                    }

                                    // Keep otherwise
                                    return startComment + commentBlock
                                            + endComment;
                                }
                            });

            final byte[] content = io.read(in);

            if (content.length != file.length()) {

                if (not(file.canWrite(), "File not writable: %s",
                        file.getAbsolutePath())) {
                    continue;
                }

                io.copy(content, file);
            }
        }
    }

    private static boolean not(boolean b, final String message,
            final Object... details) {
        b = !b;
        if (b) {
            System.err.printf(message, details);
            System.err.println();
        }
        return b;
    }
}
