// Copyright 2018 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 {
    fidl_fuchsia_bluetooth_snoop::SnoopPacket,
    std::{
        collections::{
            HashMap,
            vec_deque::{Iter as VecDequeIter, VecDeque},
        },
        time::Duration,
    },
};

use crate::{bounded_queue::{BoundedQueue, CreatedAt, SizeOf}, DeviceId};

// Size for SnoopPacket must be implemented here because SnoopPacket is defined in generated code.
impl SizeOf for SnoopPacket {
    fn size_of(&self) -> usize {
        std::mem::size_of::<Self>() + self.payload.len()
    }
}

// CreatedAt for SnoopPacket must be implemented here because SnoopPacket is defined in generated
// code.
impl CreatedAt for SnoopPacket {
    fn created_at(&self) -> Duration {
        Duration::new(self.timestamp.seconds, self.timestamp.subsec_nanos)
    }
}

/// Alias for a queue of snoop packets.
pub(crate) type PacketLog = BoundedQueue<SnoopPacket>;

/// A container for packet logs for each snoop channel.
pub(crate) struct PacketLogs {
    max_device_count: usize,
    log_size_bytes: usize,
    log_age: Duration,
    inner: HashMap<DeviceId, PacketLog>,
    insertion_order: VecDeque<DeviceId>,
}

impl PacketLogs {
    /// Create a new `PacketLogs` struct. `max_device_count` sets the number of hci devices the
    /// logger will store packets for. `log_size_bytes` sets the size limit associated with each
    /// device (see `BoundedQueue` documentation for more information). `log_age` sets the age limit
    /// associated with each device (see `BoundedQueue` documentation for more information).
    ///
    /// Note that the `log_size_bytes` and `log_age` values are set on a _per device_ basis.
    ///
    /// Panics if `max_device_count` is 0.
    pub fn new(max_device_count: usize, log_size_bytes: usize, log_age: Duration) -> PacketLogs {
        assert!(max_device_count != 0, "Cannot create a `PacketLog` with a max_device_count of 0");
        PacketLogs {
            max_device_count,
            log_size_bytes,
            log_age,
            inner: HashMap::new(),
            insertion_order: VecDeque::new(),
        }
    }

    /// Add a log to record packets for a new device. Return the `DeviceId` of the oldest log if it
    /// was removed to make room for the new device log.
    /// If the device is already being recorded, this method does nothing.
    pub fn add_device(&mut self, device: DeviceId) -> Option<DeviceId> {
        if self.inner.contains_key(&device) {
            return None;
        }
        // Add log and update insertion order metadata
        self.insertion_order.push_back(device.clone());
        self.inner.insert(device, BoundedQueue::new(self.log_size_bytes, self.log_age));

        // Remove old log and its insertion order metadata if there are too many logs
        //
        // TODO (belgum): This is a first pass at an algorithm to determine which log to drop in
        // the case of too many logs. Alternatives that can be explored in the future include
        // variations of LRU or LFU caching which may or may not account for empty device logs.
        if self.inner.len() > self.max_device_count {
            let oldest_key = self.insertion_order.pop_front()
                .expect("insertion list shouldn't be empty");
            self.inner.remove(&oldest_key);
            Some(oldest_key)
        } else {
            None
        }
    }

    /// Get a mutable reference to a single log by `DeviceId`
    pub fn get_log_mut(&mut self, device: &DeviceId) -> Option<&mut PacketLog> {
        self.inner.get_mut(device)
    }

    /// Iterator over the device ids which `PacketLogs` is currently recording packets for.
    pub fn device_ids<'a>(&'a self) -> VecDequeIter<'a, DeviceId> {
        self.insertion_order.iter()
    }

    /// Log a packet for a given device. If the device is not being logged, the packet is
    /// dropped.
    pub fn log_packet(&mut self, device: &DeviceId, packet: SnoopPacket) {
        // If the packet log has been removed, there's not much we can do with the packet.
        if let Some(packet_log) = self.inner.get_mut(device) {
            packet_log.insert(packet);
        }
    }
}
