/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * The Original Code is Protege-2000.
 *
 * The Initial Developer of the Original Code is Stanford University. Portions
 * created by Stanford University are Copyright (C) 2007.  All Rights Reserved.
 *
 * Protege was developed by Stanford Medical Informatics
 * (http://www.smi.stanford.edu) at the Stanford University School of Medicine
 * with support from the National Library of Medicine, the National Science
 * Foundation, and the Defense Advanced Research Projects Agency.  Current
 * information about Protege can be obtained at http://protege.stanford.edu.
 *
 */

package edu.stanford.smi.protege.server.socket;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

import edu.stanford.smi.protege.server.ServerProperties;
import edu.stanford.smi.protege.util.Log;

public class SimulateDelayInputStream extends FilterInputStream {
    static Logger log = Log.getLogger(SimulateDelayInputStream.class);
    private static int KB = MonitoringAspect.KB;
    
    private InputStream is;
    
    private static int bandwidth = ServerProperties.getKiloBytesPerSecondDownload();

    private int bytesRead = 0;

    
    public SimulateDelayInputStream(InputStream is) throws IOException {
        super(is);
        this.is = is;
    }
    
    @Override
    public int read() throws IOException {
        int ret = is.read();
        if (ret != -1) {
            delayForUpload(1);
        }
        return ret;
    }
    
    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        int ret = is.read(b, off, len);;
        if (ret > 0) {
            delayForUpload(ret);
        }
        return ret;
    }
    
    @Override
    public long skip(long n) throws IOException {
        long ret = super.skip(n);
        if (ret > 0) {
            delayForUpload((int) ret);
        }
        return ret;
    }
       
    private synchronized void delayForUpload(int n) {        
        bytesRead += n;
        
        if (bandwidth != 0) {
            int secondsDelay = bytesRead / (bandwidth * KB);
            if (secondsDelay > 0) {
                bytesRead -= bandwidth * KB * secondsDelay;
                try {
                    Thread.sleep(1000 * secondsDelay);
                    log.info("Simulated " + secondsDelay + " seconds of upload delay");
                } catch (InterruptedException e) {
                    log.log(Level.WARNING, "Simulation of network delay failed", e);
                }
            }
        }
    }

}
