/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * 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
 *
 *      http://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.
 */

package com.android.server;

import android.util.Log;

import java.io.Closeable;
import java.io.DataOutput;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;

/**
 * A 4k block of random {@code byte}s.
 */
class RandomBlock {

    private static final String TAG = "RandomBlock";
    private static final boolean DEBUG = false;
    private static final int BLOCK_SIZE = 4096;
    private byte[] block = new byte[BLOCK_SIZE];

    private RandomBlock() { }

    static RandomBlock fromFile(String filename) throws IOException {
        if (DEBUG) Log.v(TAG, "reading from file " + filename);
        InputStream stream = null;
        try {
            stream = new FileInputStream(filename);
            return fromStream(stream);
        } finally {
            close(stream);
        }
    }

    private static RandomBlock fromStream(InputStream in) throws IOException {
        RandomBlock retval = new RandomBlock();
        int total = 0;
        while(total < BLOCK_SIZE) {
            int result = in.read(retval.block, total, BLOCK_SIZE - total);
            if (result == -1) {
                throw new EOFException();
            }
            total += result;
        }
        return retval;
    }

    void toFile(String filename) throws IOException {
        if (DEBUG) Log.v(TAG, "writing to file " + filename);
        RandomAccessFile out = null;
        try {
            out = new RandomAccessFile(filename, "rws");
            toDataOut(out);
            truncateIfPossible(out);
        } finally {
            close(out);
        }
    }

    private static void truncateIfPossible(RandomAccessFile f) {
        try {
            f.setLength(BLOCK_SIZE);
        } catch (IOException e) {
            // ignore this exception.  Sometimes, the file we're trying to
            // write is a character device, such as /dev/urandom, and
            // these character devices do not support setting the length.
        }
    }

    private void toDataOut(DataOutput out) throws IOException {
        out.write(block);
    }

    private static void close(Closeable c) {
        try {
            if (c == null) {
                return;
            }
            c.close();
        } catch (IOException e) {
            Log.w(TAG, "IOException thrown while closing Closeable", e);
        }
    }
}
