/*!
 * Parameter Parsing Utilities
 *
 * Phase 285A1.5: Common helper for parameter name list parsing
 * Prevents infinite parser hangs on unsupported parameter type annotations
 */

use super::ParserUtils;
use crate::parser::{NyashParser, ParseError};
use crate::tokenizer::TokenType;

/// Parse parameter name list with Fail-Fast on unexpected tokens
///
/// Parses: IDENT (',' IDENT)*
/// Rejects: Type annotations, unexpected tokens, malformed comma sequences
///
/// # Arguments
/// * `p` - Mutable reference to NyashParser
/// * `context` - Context string for error messages ("method", "constructor", "function", etc.)
///
/// # Returns
/// * `Ok(Vec<String>)` - List of parameter names
/// * `Err(ParseError)` - Parse error with context-aware message
///
/// # Features
/// * Progress-zero detection: Tracks token position, errors if stuck
/// * Explicit token handling: All token types explicitly matched
/// * Fail-Fast: Either advances or errors (no infinite loop possible)
/// * Unified error messages: Single source of truth for error text
pub(crate) fn parse_param_name_list(
    p: &mut NyashParser,
    context: &str,
) -> Result<Vec<String>, ParseError> {
    let mut params = Vec::new();
    let mut last_token_position: Option<(usize, usize)> = None;

    while !p.match_token(&TokenType::RPAREN) && !p.is_at_end() {
        // Progress-zero detection: same position twice → infinite loop risk
        let current_position = p.current_position();
        if let Some(last_pos) = last_token_position {
            if current_position == last_pos {
                return Err(ParseError::InfiniteLoop {
                    location: format!("{} parameter list", context),
                    token: p.current_token().token_type.clone(),
                    line: p.current_token().line,
                });
            }
        }
        last_token_position = Some(current_position);

        match &p.current_token().token_type {
            TokenType::IDENTIFIER(param) => {
                params.push(param.clone());
                p.advance();

                if p.match_token(&TokenType::COMMA) {
                    p.advance();
                } else if !p.match_token(&TokenType::RPAREN) {
                    return Err(ParseError::UnexpectedToken {
                        found: p.current_token().token_type.clone(),
                        expected: format!(
                            "',' or ')' in {} parameter list. \
                             Note: Parameter type annotations are not supported.",
                            context
                        ),
                        line: p.current_token().line,
                    });
                }
            }
            TokenType::COMMA => {
                return Err(ParseError::UnexpectedToken {
                    found: TokenType::COMMA,
                    expected: format!("parameter name in {} parameter list", context),
                    line: p.current_token().line,
                });
            }
            _ => {
                return Err(ParseError::UnexpectedToken {
                    found: p.current_token().token_type.clone(),
                    expected: format!(
                        "parameter name or ')' in {} parameter list. \
                         Note: Parameter type annotations are not supported.",
                        context
                    ),
                    line: p.current_token().line,
                });
            }
        }
    }

    Ok(params)
}
