// Copyright 2022 The Pigweed Authors
//
// 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
//
//     https://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.

use std::{
    collections::{HashMap, HashSet},
    sync::Arc,
};

use crate::target::{Provider, Target};

/// A database of packages known to `qg`.
#[derive(Debug)]
pub struct Registry {
    /// Mapping of package slug to package. Slugs are globally unique.
    targets: HashMap<String, Arc<Target>>,

    /// All known package providers by name.
    providers: HashMap<String, Provider>,

    /// Unknown target dependencies.
    unresolved_dependencies: HashSet<String>,
}

impl Registry {
    /// Initializes an empty package registry.
    #[must_use]
    pub fn new() -> Self {
        Self {
            targets: HashMap::new(),
            providers: HashMap::new(),
            unresolved_dependencies: HashSet::new(),
        }
    }

    /// Returns the number of registered targets.
    #[must_use]
    pub fn target_count(&self) -> usize {
        self.targets.len()
    }

    /// Returns an iterator over all known targets, in arbitrary order.
    pub fn targets(&self) -> impl Iterator<Item = &Target> {
        self.targets.values().map(Arc::as_ref)
    }

    pub(crate) fn add_provider(&mut self, provider: Provider) -> bool {
        self.providers
            .insert(provider.name.clone(), provider)
            .is_none()
    }

    /// Inserts a target into the registry.
    pub(crate) fn add_target(&mut self, target: Target) -> bool {
        if !self.providers.contains_key(target.provider()) {
            return false;
        };

        let target_name = target.full_name();

        for dep in target
            .dependencies()
            .filter(|&d| !self.targets.contains_key(d))
        {
            self.unresolved_dependencies.insert(dep.into());
        }

        self.unresolved_dependencies.remove(&target_name);

        let target = Arc::new(target);
        self.targets.insert(target_name, target);

        true
    }
}

impl Default for Registry {
    fn default() -> Self {
        Self::new()
    }
}
