/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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
 *
 *     http://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 crate::{Inner, RunError, RunInput, model_attempt};
use maka_agent_facts::continuation::ContinuationClaim;
use maka_agent_facts::continuation::REPLAY_VERSION;
use maka_agent_facts::continuation::ReplayEvidence;
use maka_agent_facts::continuation::RunBoundary;
use maka_agent_facts::continuation::SessionBase;
use maka_agent_facts::event::Fact;
use maka_agent_facts::input::InvocationInput;
use maka_model::prompt::{AssistantPart, Message};
use std::{collections::BTreeSet, sync::Arc};
use tokio_util::sync::CancellationToken;

pub(super) struct PreparedClaim {
    pub claim: ContinuationClaim,
    /// Candidate evidence, not a second owner of live Session preferences.
    pub loaded_basis: BTreeSet<String>,
}

/// Derive admission evidence from the exact sealed source. The caller supplies
/// only its boundary, never a replay digest or a pre-authorized claim.
pub(super) async fn prepare(
    inner: &Arc<Inner>,
    input: &RunInput,
    source: &RunBoundary,
    catalog: &maka_tools::ToolCatalog,
    cancellation: &CancellationToken,
) -> Result<PreparedClaim, RunError> {
    let loaded_basis = inner.loaded_snapshot(&input.invocation.session_id);
    let (base, replay) =
        inspect(inner, input, source, catalog, cancellation, &loaded_basis).await?;
    let pause = match &input.work {
        crate::RunWork::Handoff { pause, .. } => Some(pause),
        _ => None,
    };
    let claim = ContinuationClaim {
        id: pause.map_or_else(
            || uuid::Uuid::new_v4().to_string(),
            |pause| pause.intent.claim_id.clone(),
        ),
        source: source.clone(),
        base,
        replay,
    };
    match pause {
        Some(pause) => pause.validate_claim(&claim, &input.invocation),
        None => claim.validate(&input.invocation),
    }
    .map_err(invalid)?;
    Ok(PreparedClaim {
        claim,
        loaded_basis,
    })
}

pub(super) async fn inspect(
    inner: &Arc<Inner>,
    input: &RunInput,
    source: &RunBoundary,
    catalog: &maka_tools::ToolCatalog,
    cancellation: &CancellationToken,
    loaded_basis: &BTreeSet<String>,
) -> Result<(SessionBase, ReplayEvidence), RunError> {
    if source.invocation.session_id != input.invocation.session_id {
        return Err(invalid("continuation belongs to another Session"));
    }
    let prefix = inner
        .log
        .run_source(
            &source.invocation.session_id,
            &source.invocation.run_id,
            None,
        )
        .await?
        .ok_or_else(|| invalid("continuation source is missing"))?;
    if prefix.boundary != *source
        || !matches!(&prefix.last.event.fact, Fact::InvocationEnded { .. })
    {
        return Err(invalid(
            "continuation source is not its exact sealed boundary",
        ));
    }
    let Fact::InvocationOpened {
        input: opening,
        configuration: Some(configuration),
    } = &prefix.opening.event.fact
    else {
        return Err(invalid("continuation source has no observed configuration"));
    };
    if input.configuration.workspace_identity.is_none()
        || input.configuration.workspace_identity != configuration.workspace_identity
    {
        return Err(invalid("continuation workspace identity changed"));
    }
    if let crate::RunWork::Handoff { pause, .. } = &input.work
        && (configuration.as_ref() != &input.configuration
            || !matches!(
                &prefix.last.event.fact,
                Fact::InvocationEnded {
                    outcome: maka_agent_facts::event::InvocationOutcome::HandoffPaused { pause: sealed }
                } if sealed == pause.as_ref()
            ))
    {
        return Err(invalid("handoff does not match its sealed source"));
    }
    let base = match opening {
        InvocationInput::Message { .. } => {
            let base = inner
                .log
                .context_before_run(&source.invocation, usize::MAX, usize::MAX)
                .await?;
            SessionBase {
                high_water: base.source_evidence.high_water,
                digest: base.source_evidence.digest,
            }
        }
        InvocationInput::Continuation { claim, .. } | InvocationInput::Handoff { claim, .. } => {
            claim.base.clone()
        }
        _ => return Err(invalid("source is not a resumable model Run")),
    };
    let context = inner
        .log
        .read_lineage_context(source, usize::MAX, usize::MAX)
        .await?;
    let prompt = model_attempt::prompt(
        inner,
        input,
        &context,
        cancellation,
        match &input.work {
            crate::RunWork::Handoff { pause, .. } => pause.execution.replay_base,
            _ => Some(base.high_water),
        },
        &input.invocation.invocation_id,
        false,
    )
    .await?;
    let tools = maka_tools::RunTools::new(
        input.configuration.language,
        inner.log.clone(),
        input.invocation.clone(),
        catalog.clone(),
        input.configuration.tool_mode,
        inner
            .cells
            .clone()
            .with_language(input.configuration.code_language),
        loaded_basis.clone().into(),
    )
    .with_model(input.provider.tool_context());
    if let crate::RunWork::Handoff { pause, .. } = &input.work {
        tools.restore(&pause.execution.tools)?;
    }
    let definitions = tools.replay_definitions();
    // Resume validates names from the full explicit inventory, including tools
    // not yet advertised through lazy discovery.
    let mut available: std::collections::HashSet<_> = catalog.names().into_iter().collect();
    available.extend(definitions.iter().map(|definition| definition.name.clone()));
    // A handoff replays settled facts, including rejected calls to unavailable
    // tools. It never executes them again; the registered catalog is checked above.
    for message in prompt
        .iter()
        .filter(|_| !matches!(input.work, crate::RunWork::Handoff { .. }))
    {
        if let Message::Assistant { content, .. } = message {
            for part in content {
                if let AssistantPart::ToolCall {
                    tool_name,
                    provider_executed,
                    ..
                } = part
                    && *provider_executed != Some(true)
                    && !available.contains(tool_name)
                {
                    return Err(invalid("continuation requires an unavailable tool"));
                }
            }
        }
    }
    let replay = replay(input, prompt, definitions, cancellation)?;
    if let crate::RunWork::Handoff { pause, .. } = &input.work
        && replay != pause.execution.replay
    {
        return Err(invalid("handoff admission replay changed after sealing"));
    }
    Ok((base, replay))
}

/// Shared by reversible handoff preparation and independently verified admission.
pub(super) fn replay<W>(
    input: &RunInput<W>,
    prompt: Vec<Message>,
    definitions: Vec<maka_model::ToolDefinition>,
    cancellation: &CancellationToken,
) -> Result<ReplayEvidence, RunError> {
    if !matches!(
        prompt.iter().find(|m| !matches!(m, Message::System { .. })),
        Some(Message::User { .. })
    ) || !matches!(
        prompt.last(),
        Some(Message::User { .. } | Message::Tool { .. })
    ) && !matches!(prompt.last(), Some(Message::Assistant { content, .. }) if matches!(content.last(), Some(AssistantPart::ToolResult { .. })))
    {
        return Err(invalid(
            "continuation requires stable user/tool replay boundaries",
        ));
    }
    let request = model_attempt::prepare_request(
        input,
        prompt,
        definitions,
        input.main_output_limit,
        maka_agent_facts::context::ModelPurpose::Main,
    )?;
    if cancellation.is_cancelled() {
        return Err(RunError::Cancelled);
    }
    Ok(ReplayEvidence {
        version: REPLAY_VERSION,
        digest: request.input_digest,
        route_identity: request.route_identity,
    })
}

fn invalid(reason: &str) -> RunError {
    RunError::ReconciliationRequired(reason.into())
}
