/*
 * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package autodeploy.slowtest;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.Scanner;
/*
 * SlowCopy.java
 *
 * Created on November 23, 2004, 12:39 PM
 */

/**
 *Provides a way to test autodeployer's behavior when an autodeployed file is
 *copied into the autodeploy directory slowly. 
 *
 *Usage:
 *
 *  java -classpath ... SlowCopy timed existing-file target-file-spec [delay-in-ms]
 *
 *where
 *<ul>
 *<le>"timed" is a keyword
 *<le>existing-file is the existing archive to be copied
 *<le>target-file-spec is the file spec of the copy to be created
 *<le>delay-in-ms is the optional time delay (in ms) to wait between writes
 *</ul>
 *
 * @author  tjquinn
 */
public class SlowCopy {
    
    /** Creates a new instance of SlowCopy */
    public SlowCopy() {
    }
  
    /** default delay between successive writes of data to the output file */
    private static final long DEFAULT_DELAY = 200; // milliseconds
    
    /** size of read and write buffer */
    private static final int BUFFER_SIZE = 1024;
    
    public static void main(String[] args) {
        try {
            new SlowCopy().run(args);
            System.exit(0);
        } catch (Throwable thr) {
            thr.printStackTrace(System.err);
            System.exit(1);
        }
    }
    
    private void run(String [] args) throws FileNotFoundException, IOException, InterruptedException {
        System.out.println(Arrays.toString(args));
        if (args.length < 3) {
            throw new IllegalArgumentException("Command line args must specify prompt/timed, the original file, and the target file");
        }
        
        /*
         *Get delay from default and override the default if the delay is 
         *specified on the command line.
         */
        long delay = DEFAULT_DELAY;
        if (args.length > 3) {
            delay = Integer.decode(args[3]);
        }
        
        /*
         *For interactive use, the tool would like to let the user press a
         *key each time a read/write is to occur.  This doesn't yet work and
         *is not used in the devtests anyway.
         */
        boolean usePromptDelay = args[0].equalsIgnoreCase("prompt");
        File oldF = new File(args[1]);
        File newF = new File(args[2]);
        
        System.out.println("Slow copy starting\n" +
                "  mode: " + args[0] + "\n" +
                "  input file: " + oldF.getAbsolutePath() + "\n" +
                "  output file: " + newF.getAbsolutePath() + "\n" +
                "  delay (if mode=timed): " + delay + "\n" +
                "  starting time: " + new Date().toString()
                );

        FileOutputStream fos = new FileOutputStream(newF);
        FileInputStream fis = new FileInputStream(oldF);
        byte [] data = new byte [BUFFER_SIZE];
        int bytesRead;
        
        Scanner scanner = null;
        boolean continuePrompting = usePromptDelay;
        String lineSep = System.getProperty("line.separator");
        
        if (usePromptDelay) {
            scanner = new Scanner(System.in);
        }
        
        int totalBytesRead = 0;
        /*
         *Repeat the cycle of reading from the input file and writing to the
         *output file, stalling for either a key press or the timed delay
         *between successive cycles.
         */
        try {
            while ((bytesRead = fis.read(data))  != -1) {
                totalBytesRead += bytesRead;
                fos.write(data, 0, bytesRead);
                if (usePromptDelay) {
                    if (scanner.hasNext(".")) {
                        String input = scanner.next(".");
                        continuePrompting = ! input.equals("q"); // just like Unix utilities - q ends
                        System.out.println("Continue prompting is now set to " + continuePrompting);
                    }
                } else {
                    /*
                     *The user wants to use timed delays, so wait for the
                     *delay period before continuing the loop.
                     */
                    Thread.currentThread().sleep(delay);
                }
            }
            System.out.println("Finished copying " + totalBytesRead + " bytes at " + new Date().toString());
            
        } finally {
            if (fos != null) {
                fos.close();
                fos = null;
            }
            if (fis != null) { 
                fis.close();
                fis = null;
            }
        }
    }
}
