//! This module tests the library's analysis capabilities on the
//! `CrypToadzCustomImage37B` contract`.
#![cfg(test)]

use storage_layout_extractor::{tc::abi::AbiType, watchdog::LazyWatchdog};

mod common;

/// Tests the library on the bytecode of the CrypToadzCustomImage37B contract
/// deployed [here](https://etherscan.io/address/0x9b679c0eb74a3e47c9d1812a1397bed24ff038e0).
#[test]
fn correctly_generates_a_layout() -> anyhow::Result<()> {
    // Create the extractor
    let bytecode = "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80639ca4936f14610030575b600080fd5b61003861004e565b60405161004591906102ff565b60405180910390f35b606061005c600060016100f2565b905090565b60008061008c836040516020016100789190610332565b6040516020818303038152906040526100c6565b90508051602082016000f091506001600160a01b0382166100c05760405163046a55db60e11b815260040160405180910390fd5b50919050565b60608151826040516020016100dc929190610358565b6040516020818303038152906040529050919050565b60606000805b60ff811660009081526020869052604090205461ffff16156101505784600082610121816103bf565b60ff9190911682526020820192909252604001600020549091506101499061ffff16836103de565b91506100f8565b60408051838101606001825290830181526000602090910181815293505b8160ff168160ff1610156101c05760ff81166000908152602086905260408120546101a1906001600160a01b03166101c9565b90506101ad85826101df565b50806101b8816103bf565b91505061016e565b50505092915050565b60606101d9826001600019610215565b92915050565b8051602082019150808201602084510184015b8184101561020a5783518152602093840193016101f2565b505082510190915250565b6060833b60008190036102385750506040805160208101909152600081526102c8565b808411156102565750506040805160208101909152600081526102c8565b8383101561028c5760405163162544fd60e11b815260048101829052602481018590526044810184905260640160405180910390fd5b83830384820360008282106102a157826102a3565b815b60408051603f8301601f19168101909152818152955090508087602087018a3c505050505b9392505050565b60005b838110156102ea5781810151838201526020016102d2565b838111156102f9576000848401525b50505050565b602081526000825180602084015261031e8160408501602087016102cf565b601f01601f19169190910160400192915050565b600081526000825161034b8160018501602087016102cf565b9190910160010192915050565b606360f81b815260e083901b6001600160e01b03191660018201526880600e6000396000f360b81b6005820152815160009061039b81600e8501602087016102cf565b91909101600e019392505050565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff81036103d5576103d56103a9565b60010192915050565b600082198211156103f1576103f16103a9565b50019056fea26469706673582212209f61681b001e967bb79aedde24b6bf1bf26e92316683a1123c25fd202b739bf164736f6c634300080d0033";
    let extractor = common::new_extractor_from_bytecode(bytecode, LazyWatchdog.in_rc())?;

    // Get the final storage layout for the input contract
    let layout = extractor.analyze()?;

    // We should see two slots
    assert_eq!(layout.slot_count(), 2);

    // `mapping(uint8 => uint16)` but we infer `mapping(bytesUnknown => number16)`
    assert!(layout.has_slot(
        0,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Bytes { length: Some(1) }),
            value_type: Box::new(AbiType::Number { size: Some(16) }),
        }
    ));

    // `mapping(uint8 => bytes20)` but we infer `mapping(bytesUnknown => bytes20)`
    assert!(layout.has_slot(
        1,
        0,
        AbiType::Mapping {
            key_type:   Box::new(AbiType::Bytes { length: None }),
            value_type: Box::new(AbiType::Bytes { length: Some(20) }),
        }
    ));

    Ok(())
}
