// Copyright (c) ZeroC, Inc.

//! This module contains test helper functions that are specific to slicec.
//! For the general purpose test helpers, see 'src/test_helpers.rs'.

// It's fine if a test doesn't need all of these functions.
#![allow(dead_code)]

use slicec::ast::Ast;
use slicec::compilation_state::CompilationState;
use slicec::compile_from_strings;
use slicec::diagnostics::Diagnostic;
use slicec::slice_options::SliceOptions;

// Re-export the general purpose test helpers to make it easier for tests to use them.
pub use slicec::test_helpers::*;

/// This function parses the provided Slice file.
/// It is the lowest level test helper function, returning a full [`CompilationState`] instead of only part of it.
/// It also allows tests to configure the compiler by passing in [`SliceOptions`].
#[must_use]
pub fn parse(slice: impl Into<String>, options: Option<&SliceOptions>) -> CompilationState {
    compile_from_strings(&[&slice.into()], options, |_| {}, |_| {})
}

/// This function parses the provided Slice file and returns the AST generated by doing so.
/// If any errors are encountered during parsing, it panics.
#[must_use]
pub fn parse_for_ast(slice: impl Into<String>) -> Ast {
    let compilation_state = parse(slice, None);
    if compilation_state.diagnostics.has_errors() {
        panic!("{:?}", compilation_state.diagnostics);
    }
    compilation_state.ast
}

/// This function parses the provided Slice files and returns the AST generated by doing so.
/// Each string is treated as a separate Slice file by the parser.
#[must_use]
pub fn parse_multiple_for_ast(slice: &[&str]) -> Ast {
    let compilation_state = compile_from_strings(slice, None, |_| {}, |_| {});
    if compilation_state.diagnostics.has_errors() {
        panic!("{:?}", compilation_state.diagnostics);
    }
    compilation_state.ast
}

/// This function parses the provided Slice file and returns any Diagnostics that were emitted during parsing.
#[must_use]
pub fn parse_for_diagnostics(slice: impl Into<String>) -> Vec<Diagnostic> {
    parse_multiple_for_diagnostics(&[&slice.into()])
}

/// This function parses the provided Slice files and returns any Diagnostics that were emitted during parsing.
/// Each string is treated as a separate Slice file by the parser.
#[must_use]
pub fn parse_multiple_for_diagnostics(slice: &[&str]) -> Vec<Diagnostic> {
    diagnostics_from_compilation_state(
        compile_from_strings(slice, None, |_| {}, |_| {}),
        &SliceOptions::default(),
    )
}

/// Asserts that the provided slice parses okay, producing no errors.
pub fn assert_parses(slice: impl Into<String>) {
    let diagnostics = parse_for_diagnostics(slice);
    let expected: [Diagnostic; 0] = []; // Compiler needs the type hint.
    check_diagnostics(diagnostics, expected);
}
