// 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 {
    crate::{
        blob_actor::BlobActor, deletion_actor::DeletionActor, instance_actor::InstanceActor,
        read_actor::ReadActor, Args, BLOBFS_MOUNT_PATH,
    },
    async_trait::async_trait,
    fidl_fuchsia_io as fio,
    fs_management::Blobfs,
    fuchsia_zircon::Vmo,
    futures::lock::Mutex,
    rand::{rngs::SmallRng, Rng, SeedableRng},
    std::sync::Arc,
    std::time::Duration,
    storage_stress_test_utils::{
        data::{Compressibility, FileFactory, UncompressedSize},
        fvm::{get_volume_path, FvmInstance, Guid},
        io::Directory,
    },
    stress_test::{actor::ActorRunner, environment::Environment, random_seed},
};

// All partitions in this test have their type set to this arbitrary GUID.
const TYPE_GUID: Guid =
    [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf];

const EIGHT_KIB: u64 = 8192;
const ONE_MIB: u64 = 1048576;
const FOUR_MIB: u64 = 4 * ONE_MIB;

/// Describes the environment that this blobfs stress test will run under.
pub struct BlobfsEnvironment {
    seed: u64,
    args: Args,
    vmo: Vmo,
    volume_guid: Guid,
    small_blob_actor: Arc<Mutex<BlobActor>>,
    medium_blob_actor: Arc<Mutex<BlobActor>>,
    large_blob_actor: Arc<Mutex<BlobActor>>,
    deletion_actor: Arc<Mutex<DeletionActor>>,
    instance_actor: Arc<Mutex<InstanceActor>>,
    read_actor: Arc<Mutex<ReadActor>>,
}

pub fn open_blobfs_root() -> Directory {
    Directory::from_namespace(
        BLOBFS_MOUNT_PATH,
        fio::OpenFlags::RIGHT_WRITABLE | fio::OpenFlags::RIGHT_READABLE,
    )
    .unwrap()
}

impl BlobfsEnvironment {
    pub async fn new(args: Args) -> Self {
        // Create the VMO that the ramdisk is backed by
        let disk_size = args.ramdisk_block_count * args.ramdisk_block_size;
        let vmo = Vmo::create(disk_size).unwrap();

        // Initialize the VMO with FVM partition style and a single blobfs partition

        // Create a ramdisk and setup FVM.
        let mut fvm =
            FvmInstance::new(true, &vmo, args.fvm_slice_size, args.ramdisk_block_size).await;

        // Create a blobfs volume
        let volume_guid = fvm.new_volume("blobfs", &TYPE_GUID, None).await;

        // Find the path to the volume
        let volume_path = get_volume_path(&volume_guid).await;

        // Initialize blobfs on volume
        let controller = fuchsia_component::client::connect_to_protocol_at_path::<
            fidl_fuchsia_device::ControllerMarker,
        >(&format!("{}/device_controller", volume_path.to_str().unwrap()))
        .unwrap();
        let mut blobfs = Blobfs::new(controller);
        blobfs.format().await.unwrap();

        let seed = match args.seed {
            Some(seed) => seed,
            None => random_seed(),
        };

        // Mount the blobfs volume
        blobfs.fsck().await.unwrap();
        let mut blobfs = blobfs.serve().await.unwrap();
        blobfs.bind_to_path(BLOBFS_MOUNT_PATH).unwrap();

        // Create the instance actor
        let instance_actor = Arc::new(Mutex::new(InstanceActor::new(fvm, blobfs)));

        let mut rng = SmallRng::seed_from_u64(seed);

        // Create the blob actors
        let small_blob_actor = {
            let rng = SmallRng::from_seed(rng.gen());
            let uncompressed_size = UncompressedSize::Exact(EIGHT_KIB);
            let compressibility = Compressibility::Uncompressible;
            let factory = FileFactory::new(rng, uncompressed_size, compressibility);
            let root_dir = open_blobfs_root();
            Arc::new(Mutex::new(BlobActor::new(factory, root_dir)))
        };

        let medium_blob_actor = {
            let rng = SmallRng::from_seed(rng.gen());
            let uncompressed_size = UncompressedSize::InRange(ONE_MIB, FOUR_MIB);
            let compressibility = Compressibility::Compressible;
            let factory = FileFactory::new(rng, uncompressed_size, compressibility);
            let root_dir = open_blobfs_root();
            Arc::new(Mutex::new(BlobActor::new(factory, root_dir)))
        };
        let large_blob_actor = {
            let rng = SmallRng::from_seed(rng.gen());
            let uncompressed_size = UncompressedSize::Exact(2 * disk_size);
            let compressibility = Compressibility::Compressible;
            let factory = FileFactory::new(rng, uncompressed_size, compressibility);
            let root_dir = open_blobfs_root();
            Arc::new(Mutex::new(BlobActor::new(factory, root_dir)))
        };

        // Create the read actor
        let read_actor = {
            let rng = SmallRng::from_seed(rng.gen());
            let root_dir = open_blobfs_root();
            Arc::new(Mutex::new(ReadActor::new(rng, root_dir)))
        };

        // Create the deletion actor
        let deletion_actor = {
            let rng = SmallRng::from_seed(rng.gen());
            let root_dir = open_blobfs_root();
            Arc::new(Mutex::new(DeletionActor::new(rng, root_dir)))
        };

        Self {
            seed,
            args,
            vmo,
            volume_guid,
            instance_actor,
            small_blob_actor,
            medium_blob_actor,
            large_blob_actor,
            read_actor,
            deletion_actor,
        }
    }
}

impl std::fmt::Debug for BlobfsEnvironment {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("Environment").field("seed", &self.seed).field("args", &self.args).finish()
    }
}

#[async_trait]
impl Environment for BlobfsEnvironment {
    fn target_operations(&self) -> Option<u64> {
        self.args.num_operations
    }

    fn timeout_seconds(&self) -> Option<u64> {
        self.args.time_limit_secs
    }

    async fn actor_runners(&mut self) -> Vec<ActorRunner> {
        let mut runners = vec![
            ActorRunner::new("small_blob_actor", None, self.small_blob_actor.clone()),
            ActorRunner::new("medium_blob_actor", None, self.medium_blob_actor.clone()),
            ActorRunner::new("large_blob_actor", None, self.large_blob_actor.clone()),
            ActorRunner::new("read_actor", None, self.read_actor.clone()),
            ActorRunner::new(
                "deletion_actor",
                Some(Duration::from_secs(10)),
                self.deletion_actor.clone(),
            ),
        ];

        if let Some(secs) = self.args.disconnect_secs {
            if secs > 0 {
                let runner = ActorRunner::new(
                    "instance_actor",
                    Some(Duration::from_secs(secs)),
                    self.instance_actor.clone(),
                );
                runners.push(runner);
            }
        }

        runners
    }

    async fn reset(&mut self) {
        {
            let mut actor = self.instance_actor.lock().await;

            // The environment is only reset when the instance is killed.
            // TODO(72385): Pass the actor error here, so it can be printed out on assert failure.
            assert!(actor.instance.is_none());

            // Create a ramdisk and setup FVM.
            let fvm = FvmInstance::new(
                false,
                &self.vmo,
                self.args.fvm_slice_size,
                self.args.ramdisk_block_size,
            )
            .await;

            // Find the path to the volume
            let volume_path = get_volume_path(&self.volume_guid).await;

            // Initialize blobfs on volume
            let controller =
                fuchsia_component::client::connect_to_protocol_at_path::<
                    fidl_fuchsia_device::ControllerMarker,
                >(&format!("{}/device_controller", volume_path.to_str().unwrap()))
                .unwrap();
            let mut blobfs = Blobfs::new(controller);

            // Mount the blobfs volume
            blobfs.fsck().await.unwrap();
            let mut blobfs = blobfs.serve().await.unwrap();
            blobfs.bind_to_path(BLOBFS_MOUNT_PATH).unwrap();

            // Replace the fvm and blobfs instances
            actor.instance = Some((blobfs, fvm));
        }

        // Replace the root directory with a new one
        {
            let mut actor = self.small_blob_actor.lock().await;
            actor.root_dir = open_blobfs_root();
        }

        {
            let mut actor = self.medium_blob_actor.lock().await;
            actor.root_dir = open_blobfs_root();
        }

        {
            let mut actor = self.large_blob_actor.lock().await;
            actor.root_dir = open_blobfs_root();
        }

        {
            let mut actor = self.read_actor.lock().await;
            actor.root_dir = open_blobfs_root();
        }

        {
            let mut actor = self.deletion_actor.lock().await;
            actor.root_dir = open_blobfs_root();
        }
    }
}
