/*******************************************************************************
* Licensed 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
*
*      https://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.
*******************************************************************************/

import java.io.*;

public class FileOperatorWin {

    public static void main(java.lang.String[] args) {
        if (args.length < 3) {
            System.out.println("Usage : java FileOperator <source> <destination> {CRDL}");
            System.exit(1);
        }
        try {
            FileOperator fo = new FileOperator();
            File src = new File(args[0]);
            File dst = new File(args[1]);

            switch (args[2].charAt(0)) {
            case 'C':
                System.out.println("File Copy Test :");
                System.out.println("Original Directory :");
                fo.list(src, 3);
                fo.xcopy(src, dst);
                System.out.println("Copied Directory :");
                fo.list(dst, 3);
                System.out.print("Compare : ");
                if (fo.compare(src, dst))
                    System.out.println("Passed");
                else
                    System.out.println("Failed");

                break;

            case 'R':
                System.out.println("File Rename Test :");
                System.out.println("Original Directory :");
                fo.list(dst, 3);
                File newdir = fo.rename(dst);
                if (newdir != null) {
                    System.out.println("Renamed Directory :");
                    fo.list(newdir, 3);

                    System.out.println("Rename-back : ");
                    dst = fo.rename(newdir);

                    System.out.println("Renamed Directory :");
                    fo.list(dst, 3);
                    System.out.print("Compare : ");
                    if (fo.compare(src, dst))
                        System.out.println("Passed");
                    else
                        System.out.println("Failed");

                } else
                    System.out.println("Rename Failed");
                break;

            case 'D':
                System.out.println("File Delete Test :");
                System.out.println("Original Directory :");
                fo.list(dst, 3);
                fo.delete(dst);
                System.out.println("Deleted Directory :");
                fo.list(dst, 3);
                break;

            case 'L':
                fo.list(src, 3);
                break;
            }

        } catch (java.io.IOException e) {
            e.printStackTrace();
        }
    }

    public static void xcopy(File src, File dst) throws java.io.IOException {
        if (!src.exists() || !src.isDirectory())
            return;
        if (!dst.exists())
            dst.mkdirs();
        else if (!dst.isDirectory()) {
            dst.delete();
            dst.mkdirs();
        }
        String names[] = src.list();
        for (int i = 0; i < names.length; i++) {
            File s = new File(src, names[i]);
            File d = new File(dst, names[i]);
            if (s.isFile()) {
                copy(s, d);
            } else if (s.isDirectory()) {
                xcopy(s, d);
            }
        }
    }

    public static void delete(File dst) {
        if (!dst.exists())
            return;
        if (dst.isDirectory()) {
            String names[] = dst.list();
            for (int i = 0; i < names.length; i++) {
                delete(new File(dst, names[i]));
            }
        }
        dst.delete();
    }

    public static File rename(File src) {
        if (!src.exists())
            return null;
        if (src.isDirectory()) {
            String names[] = src.list();
            for (int i = 0; i < names.length; i++) {
                rename(new File(src, names[i]));
            }
        }
        String name = src.getName();
        File dst = new File(src.getParent(), reverse(name));
        src.renameTo(dst);
        return dst;
    }

    public static void list(File src, int indent) {
        if (!src.exists())
            return;
        for (int i = 0; i < indent; i++)
            System.out.print(" ");
        System.out.println(src.getName());
        if (src.isDirectory()) {
            String names[] = src.list();
            java.util.Arrays.sort(names);
            for (int i = 0; i < names.length; i++)
                list(new File(src, names[i]), indent + 3);
        }
    }

    public static boolean compare(File src, File dst) {
        if (!src.exists())
            if (!dst.exists())
                return true;
            else {
                System.err.println(src.toString() + " doesn't exist.");
                return false;
            }
        if (!dst.exists()) {
            System.err.println(dst.toString() + " doesn't exist.");
            return false;
        }
        if (!src.getName().equals(dst.getName())) {
            System.err.println("Name Mismatch : " + src + " vs " + dst);
            return false;
        }
        if (src.isDirectory()) {
            if (!dst.isDirectory()) {
                System.err.println(dst.toString() + " is not a directory.");
                return false;
            }
            String srclist[] = src.list();
            String dstlist[] = dst.list();
            if (srclist.length != dstlist.length) {
                System.err.println("Contents Number Mismatch : " + src + " vs " + dst);
                return false;
            }
            for (int i = 0; i < srclist.length; i++)
                return compare(new File(src, srclist[i]), new File(dst, srclist[i]));
            for (int i = 0; i < dstlist.length; i++)
                return compare(new File(src, dstlist[i]), new File(dst, dstlist[i]));
        }
        return true;
    }

    public static String reverse(String src) {
        if (src == null)
            return null;
        String dst = new String("");
        for (int i = 0; i < src.length(); i++) {
            dst = src.charAt(i) + dst;
        }
        return dst;
    }

    public static void copy(File src, File dst) throws java.io.IOException {
        FileInputStream fi = new FileInputStream(src);
        FileOutputStream fo = new FileOutputStream(dst);
        byte buf[] = new byte[1000];
        int num = 0;
        while ((num = fi.read(buf)) >= 0) {
            fo.write(buf, 0, num);
        }
        fi.close();
        fo.close();
        return;
    }

}
