// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use {
    async_trait::async_trait,
    fidl_fuchsia_io as fio,
    fuchsia_zircon::Status,
    log::{debug, info},
    rand::{prelude::SliceRandom, rngs::SmallRng, Rng},
    storage_stress_test_utils::io::Directory,
    stress_test::actor::{Actor, ActorError},
};

// Performs operations on blobs expected to exist on disk
pub struct ReadActor {
    // Random number generator used by the operator
    pub rng: SmallRng,

    // Blobfs root directory
    pub root_dir: Directory,
}

impl ReadActor {
    pub fn new(rng: SmallRng, root_dir: Directory) -> Self {
        Self { rng, root_dir }
    }

    // Read a random amount of data at a random offset from a random blob
    async fn read_blob(&mut self) -> Result<(), Status> {
        // Decide how many blobs to create new handles for
        let blob_list = self.root_dir.entries().await?;

        if blob_list.is_empty() {
            // No blobs to read!
            return Ok(());
        }

        // Choose a random blob and open a handle to it
        let blob = blob_list.choose(&mut self.rng).unwrap();
        let file = self.root_dir.open_file(blob, fio::OpenFlags::RIGHT_READABLE).await?;

        debug!("Reading from {}", blob);
        let data_size_bytes = file.uncompressed_size().await?;

        if data_size_bytes == 0 {
            // Nothing to read, blob is empty!
            return Ok(());
        }

        // Choose an offset
        let offset = self.rng.gen_range(0..data_size_bytes - 1);

        // Determine the length of this read
        let end_pos = self.rng.gen_range(offset..data_size_bytes);

        assert!(end_pos >= offset);
        let length = end_pos - offset;

        // Read the data from the handle and verify it
        file.seek(fio::SeekOrigin::Start, offset).await?;
        let actual_data_bytes = file.read_num_bytes(length).await?;
        assert_eq!(actual_data_bytes.len(), length as usize);

        debug!("Read {} bytes from {}", length, blob);
        Ok(())
    }
}

#[async_trait]
impl Actor for ReadActor {
    async fn perform(&mut self) -> Result<(), ActorError> {
        match self.read_blob().await {
            Ok(()) => Ok(()),
            Err(Status::NOT_FOUND) => Ok(()),
            // Any other error is assumed to come from an intentional crash.
            // The environment verifies that an intentional crash occurred
            // and will panic if that is not the case.
            Err(s) => {
                info!("Read actor got status: {}", s);
                Err(ActorError::ResetEnvironment)
            }
        }
    }
}
