"""
Resource and time series merging for billing data generation.

Extracted from the existing pipeline with cartesian product optimization.
"""

import polars as pl


def merge_resources_with_time_series(
    resources_df: pl.DataFrame, time_series_df: pl.DataFrame
) -> pl.DataFrame:
    """
    Performs a cartesian product of resources and hourly timestamps,
    applying the hourly cost to each resource.
    
    Args:
        resources_df: DataFrame containing resource information
        time_series_df: DataFrame containing hourly timestamps and costs
        
    Returns:
        DataFrame with merged resource and time data
    """
    if resources_df.is_empty() or time_series_df.is_empty():
        return pl.DataFrame()

    # Create keys to join on (cross join workaround)
    resources_df = resources_df.with_columns(pl.lit(1).alias("_merge_key"))
    time_series_df = time_series_df.with_columns(pl.lit(1).alias("_merge_key"))

    merged = resources_df.join(time_series_df, on="_merge_key", how="inner").drop(
        "_merge_key"
    )

    # Rename cost column to match final schema
    return merged.rename({"hourly_cost": "cost"})


def estimate_memory_usage(
    record_count: int,
    bytes_per_record: int = 151
) -> int:
    """
    Estimate memory usage for a given number of records.
    
    Args:
        record_count: Number of records to estimate for
        bytes_per_record: Average bytes per record in Polars DataFrame
        
    Returns:
        Estimated memory usage in bytes
    """
    return record_count * bytes_per_record


def should_split_job(
    estimated_memory_bytes: int,
    target_memory_bytes: int = 1024 * 1024 * 1024  # 1GB default
) -> bool:
    """
    Determine if a job should be split based on memory usage.
    
    Args:
        estimated_memory_bytes: Estimated memory usage in bytes
        target_memory_bytes: Target memory limit in bytes
        
    Returns:
        True if job should be split, False otherwise
    """
    return estimated_memory_bytes > target_memory_bytes