// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/**
*******************************************************************************
* Copyright (C) 2005-2010, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*/

package com.ibm.icu.dev.tool.docs;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class Deprecator {
    private boolean undep;
    private int log;

    Deprecator(boolean undep, int log) {
        this.undep = undep;
        this.log = log;
    }

    public static void main(String[] args) {
        String srcPath = null;
        String dstPath = null;
        boolean undep = false;

        int log = 1;
        boolean help = false;
        StringBuffer err = new StringBuffer();

        for (int i = 0; i < args.length; ++i) {
            String arg = args[i];
            if (arg.equals("-src")) {
                srcPath = args[++i];
            } else if (arg.equals("-dst")) {
                dstPath = args[++i];
            } else if (arg.equals("-undep")) {
                undep = true;
            } else if (arg.equals("-help")) {
                help = true;
            } else if (arg.equals("-silent")) {
                log = 0;
            } else if (arg.equals("-log")) {
                log = 2;
            } else if (arg.equals("-logfiles")) {
                log = 3;
            } else if (arg.equals("-verbose")) {
                log = 4;
            } else {
                err.append("\nunrecognized argument: " + arg);
            }
        }

        File srcDir = null;
        File dstDir = null;

        if (srcPath == null) {
            err.append("\nsrc must be defined");
        } else {
            srcDir = new File(srcPath);
            if (!(srcDir.exists() && srcDir.isDirectory())) {
                err.append("\nsrc must be an existing directory: '" + srcPath + "'");
            }
        }
        if (dstPath == null) {
            err.append("\ndst must be defined");
        } else {
            dstDir = new File(dstPath);
            if (!dstDir.exists()) {
                if (!dstDir.mkdirs()) {
                    err.append("\nunable to create dst: '" + dstPath + "'");
                }
            } else if (!dstDir.isDirectory()) {
                err.append("\ndst exists but is not directory: '" + dstPath + "'");
            }
        }

        if (help || err.length() > 0) {
            if (!help) {
                System.err.println("Error: " + err.toString());
            }
            usage();
            return;
        }

        try {
            if (log > 0) {
                System.out.println("src: " + srcDir.getCanonicalPath());
                System.out.println("dst: " + dstDir.getCanonicalPath());
                System.out.println("undep: " + undep);
                System.out.flush();
            }

            new Deprecator(undep, log).process(srcDir, dstDir);

            if (log > 0) {
                System.out.println("done");
                System.out.flush();
            }
        }
        catch(Exception e) {
            System.err.println("Unexpected error: " + e);
        }
    }

    static void usage() {
        PrintWriter pw = new PrintWriter(System.out);
        pw.println("Usage: Deprecator -src path -dst path [-help]");
        pw.println("  -src path : the root of the tree of files to work on");
        pw.println("  -dst path : the root of the tree to put the resulting files");
        pw.println("  -help     : print this usage message and exit, doing nothing");
        pw.println("  -undep    : remove deprecation tags if present (default false)");
        pw.println();
        pw.println("  Add or remove warning deprecations for ICU @draft and @internal APIs");
        pw.flush();
    }

    static final String stoplist = "!CVS";
    static final FilenameFilter ff = new FilenameFilter() {
            public boolean accept(File dir, String name) {
                if (name.endsWith(".java")) return true;
                if (new File(dir, name).isDirectory()) {
                    if (stoplist.indexOf("!"+name) == -1) {
                        return true;
                    }
                }
                return false;
            }
        };
            
    void process(File srcDir, File dstDir) {
        File[] files = srcDir.listFiles(ff);
        for (int i = 0; i < files.length; ++i) {
            File f = files[i];
            File d = new File(dstDir, f.getName());
            if (f.isDirectory()) {
                if (!d.exists()) {
                    if (!d.mkdir()) {
                        System.err.println("cannot create directory: " + d.getPath());
                        continue;
                    }
                } else if (!d.isDirectory()) {
                    System.err.println("file already exists but is not directory: " + d.getPath());
                    continue;
                }
                if (log > 1) {
                    System.out.println("process dir: " + f.getPath());
                }
                process(f, d);
            } else {
                processFile(f, d);
            }
        }
    }

    /*
 @ deprecated
 *** @deprecated
 ** ** ** @deprecated
    */
    static final Pattern pat = Pattern.compile("^[\\s*]*@\\s*deprecated.*");

    void processFile(File srcFile, File dstFile) {
        if (log > 2) {
            System.out.println("process '" + srcFile.getPath() + "'");
        }

        try {
            BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(srcFile)));
            int n = 0;
            String line = null;
            while (null != (line = r.readLine())) {
                ++n;
                Matcher m = pat.matcher(line);
                if (m.matches()) {
                    if (log > 3) {
                        System.out.println(String.valueOf(n) + ": " + line);
                    }
                }
            }
            r.close();
        }
        catch (Exception e) {
            System.out.flush();
            System.err.println("caught exception: " + e);
        }
    }
}
