class HypervisorUtils {

    public static void checkVolumeFileForActivity(final String filePath, int timeoutSeconds, long inactiveThresholdMilliseconds, long minimumFileSize) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new CloudRuntimeException("File " + file.getAbsolutePath() + " not found");
        }
        if (file.length() < minimumFileSize) {
            s_logger.debug("VM disk file too small, fresh clone? skipping modify check");
            return;
        }
        int waitedSeconds = 0;
        int intervalSeconds = 1;
        while (true) {
            BasicFileAttributes attrs = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
            long modifyIdle = System.currentTimeMillis() - attrs.lastModifiedTime().toMillis();
            long accessIdle = System.currentTimeMillis() - attrs.lastAccessTime().toMillis();
            if (modifyIdle > inactiveThresholdMilliseconds && accessIdle > inactiveThresholdMilliseconds) {
                s_logger.debug("File " + filePath + " has not been accessed or modified for at least " + inactiveThresholdMilliseconds + " ms");
                return;
            } else {
                s_logger.debug("File was modified " + modifyIdle + "ms ago, accessed " + accessIdle + "ms ago, waiting for inactivity threshold of "
                        + inactiveThresholdMilliseconds + "ms or timeout of " + timeoutSeconds + "s (waited " + waitedSeconds + "s)");
            }
            try {
                TimeUnit.SECONDS.sleep(intervalSeconds);
            } catch (InterruptedException ex) {
                throw new CloudRuntimeException("Interrupted while waiting for activity on " + filePath + " to subside", ex);
            }
            waitedSeconds += intervalSeconds;
            if (waitedSeconds >= timeoutSeconds) {
                throw new CloudRuntimeException("Reached timeout while waiting for activity on " + filePath + " to subside");
            }
        }
    }

}