/**
 * FetchContext.java
 * 
 * Context information provided to content fetchers about why a fetch was triggered.
 * 
 * This class is part of the Integration Point Refactor (PR1) SPI implementation.
 * It provides fetchers with metadata about the fetch request, including trigger
 * type, scheduling information, and optional metadata.
 * 
 * @author Matthew Raymer
 * @version 1.0.0
 */

package org.timesafari.dailynotification;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Context provided to content fetchers about why fetch was triggered
 * 
 * This follows the TypeScript interface from src/types/content-fetcher.ts and
 * ensures type safety between JS and native fetcher implementations.
 */
public class FetchContext {
    
    /**
     * Reason why the fetch was triggered
     * 
     * Valid values: "background_work", "prefetch", "manual", "scheduled"
     */
    @NonNull
    public final String trigger;
    
    /**
     * When notification is scheduled for (optional, epoch milliseconds)
     * 
     * Only present when trigger is "prefetch" or "scheduled"
     */
    @Nullable
    public final Long scheduledTime;
    
    /**
     * When the fetch was triggered (required, epoch milliseconds)
     */
    public final long fetchTime;
    
    /**
     * Additional context metadata (optional)
     * 
     * Plugin may populate with app state, network info, etc.
     * Fetcher can use for logging, debugging, or conditional logic.
     */
    @NonNull
    public final Map<String, Object> metadata;
    
    /**
     * Constructor with all fields
     * 
     * @param trigger Trigger type (required)
     * @param scheduledTime Scheduled time (optional)
     * @param fetchTime When fetch triggered (required)
     * @param metadata Additional metadata (optional, can be null)
     */
    public FetchContext(
            @NonNull String trigger,
            @Nullable Long scheduledTime,
            long fetchTime,
            @Nullable Map<String, Object> metadata) {
        if (trigger == null || trigger.isEmpty()) {
            throw new IllegalArgumentException("trigger is required");
        }
        
        this.trigger = trigger;
        this.scheduledTime = scheduledTime;
        this.fetchTime = fetchTime;
        this.metadata = metadata != null ? 
            Collections.unmodifiableMap(new HashMap<>(metadata)) : 
            Collections.emptyMap();
    }
    
    /**
     * Constructor with minimal fields (no metadata)
     * 
     * @param trigger Trigger type
     * @param scheduledTime Scheduled time (can be null)
     * @param fetchTime When fetch triggered
     */
    public FetchContext(
            @NonNull String trigger,
            @Nullable Long scheduledTime,
            long fetchTime) {
        this(trigger, scheduledTime, fetchTime, null);
    }
    
    /**
     * Get metadata value by key
     * 
     * @param key Metadata key
     * @return Value or null if not present
     */
    @Nullable
    public Object getMetadata(@NonNull String key) {
        return metadata.get(key);
    }
    
    /**
     * Check if metadata contains key
     * 
     * @param key Metadata key
     * @return True if key exists
     */
    public boolean hasMetadata(@NonNull String key) {
        return metadata.containsKey(key);
    }
    
    @Override
    public String toString() {
        return "FetchContext{" +
            "trigger='" + trigger + '\'' +
            ", scheduledTime=" + scheduledTime +
            ", fetchTime=" + fetchTime +
            ", metadataSize=" + metadata.size() +
            '}';
    }
}

