// Copyright 2026 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::HashSet;

use anyhow::{Result, anyhow};

use crate::ArchConfigInterface;
use crate::system_config::{ConstConfig, SystemConfig};

pub trait ManifestValidator<A: ArchConfigInterface> {
    fn validate(&self, config: &SystemConfig<A>) -> Result<()>;
}

fn check_ident(name: &str, context: &str) -> Result<()> {
    if syn::parse_str::<syn::Ident>(name).is_err() {
        return Err(anyhow!(
            "Invalid Rust identifier `{}` found in {}",
            name,
            context
        ));
    }
    if name.to_lowercase() != name {
        return Err(anyhow!(
            "Invalid identifier `{}` in {}: must be all lowercase.",
            name,
            context
        ));
    }
    Ok(())
}

struct IdentifierValidatorContext<'a> {
    seen: HashSet<&'a str>,
}

impl<'a> IdentifierValidatorContext<'a> {
    fn new() -> Self {
        Self {
            seen: HashSet::new(),
        }
    }

    fn check(&mut self, name: &'a str, context: &str) -> Result<()> {
        check_ident(name, context)?;
        if !self.seen.insert(name) {
            return Err(anyhow!("Duplicate {}", context));
        }
        Ok(())
    }
}

pub struct IdentifierValidator;

impl<A: ArchConfigInterface> ManifestValidator<A> for IdentifierValidator {
    fn validate(&self, config: &SystemConfig<A>) -> Result<()> {
        let mut app_names = IdentifierValidatorContext::new();
        let mut process_names = IdentifierValidatorContext::new();
        for app in &config.base.apps {
            app_names.check(app.name.as_str(), &format!("app `{}`", app.name))?;

            let mut constant_names = IdentifierValidatorContext::new();
            for constant in &app.constants {
                let const_name = match constant {
                    ConstConfig::Bool { name, .. } => name,
                    ConstConfig::Char { name, .. } => name,
                    ConstConfig::U8 { name, .. } => name,
                    ConstConfig::U16 { name, .. } => name,
                    ConstConfig::U32 { name, .. } => name,
                    ConstConfig::U64 { name, .. } => name,
                    ConstConfig::U128 { name, .. } => name,
                    ConstConfig::Usize { name, .. } => name,
                    ConstConfig::I8 { name, .. } => name,
                    ConstConfig::I16 { name, .. } => name,
                    ConstConfig::I32 { name, .. } => name,
                    ConstConfig::I64 { name, .. } => name,
                    ConstConfig::I128 { name, .. } => name,
                    ConstConfig::Isize { name, .. } => name,
                    ConstConfig::String { name, .. } => name,
                };
                let context = format!("constant `{}` in app `{}`", const_name, app.name);
                constant_names.check(const_name.as_str(), &context)?;
            }

            for process in &app.processes {
                let context = format!("process `{}` in app `{}`", process.name, app.name);
                process_names.check(process.name.as_str(), &context)?;

                let mut memory_mapping_names = IdentifierValidatorContext::new();
                for mapping in &process.memory_mappings {
                    let context = format!(
                        "memory mapping `{}` in process `{}`",
                        mapping.name, process.name
                    );
                    memory_mapping_names.check(mapping.name.as_str(), &context)?;
                }

                let mut object_names = IdentifierValidatorContext::new();
                for object in &process.objects {
                    let context =
                        format!("object `{}` in process `{}`", object.name(), process.name);
                    object_names.check(object.name(), &context)?;
                }

                let thread_count = &process.threads().count();
                if *thread_count < 1 {
                    return Err(anyhow!(
                        "Process `{}` has no threads. At least one thread must be declared.",
                        process.name,
                    ));
                }

                let main_thread_count = &process
                    .threads()
                    .filter(|thread| thread.main_thread)
                    .count();
                if *main_thread_count > 1 {
                    return Err(anyhow!(
                        "Process `{}` has multiple `main_thread` flags. Only one `main_thread` may be declared.",
                        process.name,
                    ));
                }

                if *thread_count > 1 && *main_thread_count < 1 {
                    return Err(anyhow!(
                        concat!(
                            "Process `{}` has multiple threads but none are marked with `main_thread: true`. ",
                            "At least one thread must be the `main_thread` when multiple are defined.",
                        ),
                        process.name,
                    ));
                }
            }
        }
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::system_config::{AppConfig, BaseConfig, KernelConfig, ProcessConfig};

    struct MockArch;
    impl crate::ArchConfigInterface for MockArch {
        fn get_arch_crate_name(&self) -> &'static str {
            "mock"
        }
        fn get_start_fn_address(&self, _flash: u64) -> u64 {
            0
        }
        fn calculate_and_validate_config(&mut self, _config: &mut BaseConfig) -> Result<()> {
            Ok(())
        }
        fn get_interrupt_table_link_section(&self) -> Option<String> {
            None
        }
        fn bare_interrupt_table_entries(&self) -> bool {
            false
        }
    }

    fn make_mock_config() -> SystemConfig<MockArch> {
        SystemConfig {
            arch: MockArch,
            base: BaseConfig {
                kernel: KernelConfig {
                    flash_start_address: 0,
                    flash_size_bytes: 0,
                    ram_start_address: 0,
                    ram_size_bytes: 0,
                    interrupt_table: None,
                    mpu_validation: crate::mpu_validation::MpuValidationMode::Permissive,
                },
                apps: vec![],
                arch_crate_name: "mock",
                userspace: true,
                bare_interrupt_table_entries: false,
            },
        }
    }

    #[test]
    fn test_identifier_validator_rust_ident() {
        let mut config = make_mock_config();
        config.base.apps.push(AppConfig {
            name: "valid_app".to_string(),
            flash_size_bytes: 0,
            ram_size_bytes: 0,
            processes: vec![ProcessConfig {
                name: "valid_process".to_string(),
                ram_size_bytes: 0,
                ram_start_address: 0,
                memory_mappings: vec![crate::system_config::MemoryMapping {
                    name: "valid_mapping".to_string(),
                    ty: crate::system_config::MemoryMappingType::ReadOnlyExecutable,
                    start_address: 0,
                    size_bytes: 0,
                }],
                objects: vec![crate::system_config::ObjectConfig::Thread(
                    crate::system_config::ThreadObjectConfig {
                        name: "valid_thread_obj".to_string(),
                        kernel_stack_size_bytes: None,
                        priority: None,
                        stack_size_expression: "".to_string(),
                        main_thread: false,
                    },
                )],
                main_thread_name: None,
            }],
            constants: vec![ConstConfig::U32 {
                name: "valid_const".to_string(),
                value: 0,
            }],
            flash_start_address: 0,
            ram_start_address: 0,
            start_fn_address: 0,
            initial_sp: 0,
        });

        let validator = IdentifierValidator;
        validator.validate(&config).unwrap();

        // Invalid app name (syntax)
        config.base.apps[0].name = "invalid-name".to_string();
        assert!(validator.validate(&config).is_err());
        config.base.apps[0].name = "valid_app".to_string();

        // Invalid app name (must be lowercase)
        config.base.apps[0].name = "InvalidApp".to_string();
        assert!(validator.validate(&config).is_err());
        config.base.apps[0].name = "valid_app".to_string();

        // Invalid mapping name
        config.base.apps[0].processes[0].memory_mappings[0].name = "InvalidMapping".to_string();
        assert!(validator.validate(&config).is_err());
        config.base.apps[0].processes[0].memory_mappings[0].name = "valid_mapping".to_string();

        // Invalid constant name
        config.base.apps[0].constants[0] = ConstConfig::U32 {
            name: "let".to_string(),
            value: 0,
        };
        assert!(validator.validate(&config).is_err());
        config.base.apps[0].constants[0] = ConstConfig::U32 {
            name: "valid_const".to_string(),
            value: 0,
        };
    }

    #[test]
    fn test_identifier_validator_uniqueness() {
        let mut config = make_mock_config();
        let app1 = AppConfig {
            name: "app1".to_string(),
            flash_size_bytes: 0,
            ram_size_bytes: 0,
            processes: vec![ProcessConfig {
                name: "proc1".to_string(),
                ram_size_bytes: 0,
                ram_start_address: 0,
                memory_mappings: vec![crate::system_config::MemoryMapping {
                    name: "mapping1".to_string(),
                    ty: crate::system_config::MemoryMappingType::ReadOnlyExecutable,
                    start_address: 0,
                    size_bytes: 0,
                }],
                objects: vec![crate::system_config::ObjectConfig::Thread(
                    crate::system_config::ThreadObjectConfig {
                        name: "thread1".to_string(),
                        kernel_stack_size_bytes: None,
                        priority: None,
                        stack_size_expression: "".to_string(),
                        main_thread: true,
                    },
                )],
                main_thread_name: None,
            }],
            constants: vec![ConstConfig::U32 {
                name: "const1".to_string(),
                value: 0,
            }],
            flash_start_address: 0,
            ram_start_address: 0,
            start_fn_address: 0,
            initial_sp: 0,
        };
        config.base.apps.push(app1.clone());

        let validator = IdentifierValidator;
        validator.validate(&config).unwrap();

        // Duplicate app name
        config.base.apps.push(app1.clone());
        assert!(validator.validate(&config).is_err());

        // Resolve duplicate app name but leave duplicate process name
        config.base.apps[1].name = "app2".to_string();
        assert!(validator.validate(&config).is_err());

        // Resolve duplicate process name
        config.base.apps[1].processes[0].name = "proc2".to_string();
        validator.validate(&config).unwrap();

        // Duplicate memory mapping name
        let m = config.base.apps[0].processes[0].memory_mappings[0].clone();
        config.base.apps[0].processes[0].memory_mappings.push(m);
        assert!(validator.validate(&config).is_err());
        config.base.apps[0].processes[0].memory_mappings.pop();

        // Duplicate constant
        let c = config.base.apps[0].constants[0].clone();
        config.base.apps[0].constants.push(c);
        assert!(validator.validate(&config).is_err());
        config.base.apps[0].constants.pop();

        // Duplicate object name
        let o = config.base.apps[0].processes[0].objects[0].clone();
        config.base.apps[0].processes[0].objects.push(o);
        assert!(validator.validate(&config).is_err());
        config.base.apps[0].processes[0].objects.pop();

        // No thread objects should cause an error.
        let t = config.base.apps[0].processes[0].objects[0].clone();
        config.base.apps[0].processes[0].objects.pop();
        assert!(validator.validate(&config).is_err());
        config.base.apps[0].processes[0].objects.push(t);

        // Multiple main_thread flags should error.
        config.base.apps[0].processes[0]
            .objects
            .push(crate::system_config::ObjectConfig::Thread(
                crate::system_config::ThreadObjectConfig {
                    name: "thread2".to_string(),
                    kernel_stack_size_bytes: None,
                    priority: None,
                    stack_size_expression: "".to_string(),
                    main_thread: true,
                },
            ));
        assert!(validator.validate(&config).is_err());
        config.base.apps[0].processes[0].objects.pop();

        // Multiple threads without a main_thread flag should error.
        let t2 = config.base.apps[0].processes[0].objects[0].clone();
        config.base.apps[0].processes[0].objects.pop();
        config.base.apps[0].processes[0]
            .objects
            .push(crate::system_config::ObjectConfig::Thread(
                crate::system_config::ThreadObjectConfig {
                    name: "thread3".to_string(),
                    kernel_stack_size_bytes: None,
                    priority: None,
                    stack_size_expression: "".to_string(),
                    main_thread: false,
                },
            ));
        config.base.apps[0].processes[0]
            .objects
            .push(crate::system_config::ObjectConfig::Thread(
                crate::system_config::ThreadObjectConfig {
                    name: "thread4".to_string(),
                    kernel_stack_size_bytes: None,
                    priority: None,
                    stack_size_expression: "".to_string(),
                    main_thread: false,
                },
            ));
        assert!(validator.validate(&config).is_err());
        config.base.apps[0].processes[0].objects.pop();
        config.base.apps[0].processes[0].objects.pop();
        config.base.apps[0].processes[0].objects.push(t2);
    }
}
