/*
 * 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 maka_code_runtime::{CellContext, CellDiagnostic, CellDiagnosticKind, CellOutput};
use serde_json::{Value, json};

pub(crate) fn invoke(
    name: &str,
    mut args: Vec<Value>,
    mut kwargs: serde_json::Map<String, Value>,
    context: &CellContext,
) -> Result<Value, CellDiagnostic> {
    for value in args.iter().chain(kwargs.values()) {
        crate::protocol::validate_json(value)?;
    }
    let fields: &[&str] = match name {
        "text" | "notify" | "audio" | "generated_image" => &["value"],
        "image" => &["value", "detail"],
        "store" => &["key", "value"],
        "load" => &["key"],
        "exit" | "yield_control" => &[],
        _ => return Err(error("unknown Python helper")),
    };
    if args.len() > fields.len() {
        return Err(error("too many helper arguments"));
    }
    for field in fields.iter().take(args.len()) {
        if kwargs.contains_key(*field) {
            return Err(error("argument supplied twice"));
        }
    }
    for field in fields.iter().skip(args.len()) {
        match kwargs.remove(*field) {
            Some(value) => args.push(value),
            None if name == "image" && *field == "detail" => args.push(Value::Null),
            None => return Err(error(format!("missing argument: {field}"))),
        }
    }
    if !kwargs.is_empty() {
        return Err(error("unknown helper keyword argument"));
    }
    match name {
        "text" => context.emit(CellOutput::Text {
            text: display(&args[0]),
        })?,
        "notify" => context.notify(display(&args[0]))?,
        "store" => context.store(key(&args[0])?.into(), args[1].clone())?,
        "load" => return Ok(context.load(key(&args[0])?).unwrap_or(Value::Null)),
        "yield_control" => context.yield_output(),
        "exit" => {}
        "image" => {
            let value = &args[0];
            let detail = if !args[1].is_null() {
                args[1].clone()
            } else {
                value
                    .get("detail")
                    .or_else(|| value.pointer("/_meta/codex~1imageDetail"))
                    .cloned()
                    .unwrap_or(Value::Null)
            };
            if value.get("ref").is_some() {
                emit(
                    context,
                    json!({"kind":"image","image":{"mimeType":value.get("mimeType"),"ref":value.get("ref"),"detail":detail}}),
                )?;
            } else {
                media(
                    context,
                    "image",
                    value.get("image_url").unwrap_or(value),
                    detail,
                )?;
            }
        }
        "audio" => media(
            context,
            "audio",
            args[0].get("audio_url").unwrap_or(&args[0]),
            Value::Null,
        )?,
        "generated_image" => {
            media(
                context,
                "image",
                args[0]
                    .get("image_url")
                    .ok_or_else(|| error("missing image_url"))?,
                Value::Null,
            )?;
            if let Some(hint) = args[0].get("output_hint").filter(|value| !value.is_null()) {
                context.emit(CellOutput::Text {
                    text: display(hint),
                })?;
            }
        }
        _ => unreachable!(),
    }
    Ok(Value::Null)
}
fn media(
    context: &CellContext,
    kind: &str,
    value: &Value,
    detail: Value,
) -> Result<(), CellDiagnostic> {
    let content = if let Some(url) = value.as_str() {
        let (mime, data) = url
            .strip_prefix("data:")
            .and_then(|value| value.split_once(";base64,"))
            .ok_or_else(|| error("expected a base64 data URL"))?;
        if !mime.starts_with(&format!("{kind}/"))
            || !data
                .trim_end_matches('=')
                .bytes()
                .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'+' | b'/'))
            || data.len() - data.trim_end_matches('=').len() > 2
        {
            return Err(error("expected a base64 data URL"));
        }
        json!({"type":kind,"mimeType":mime,"data":data})
    } else {
        if value.get("type").and_then(Value::as_str) != Some(kind) {
            return Err(error(format!("expected a {kind} content block")));
        }
        json!({"type":kind,"mimeType":value.get("mimeType"),"data":value.get("data")})
    };
    emit(
        context,
        json!({"kind":"media","content":content,"detail":detail}),
    )
}
fn emit(context: &CellContext, value: Value) -> Result<(), CellDiagnostic> {
    context.emit(serde_json::from_value(value).map_err(error)?)
}
fn key(value: &Value) -> Result<&str, CellDiagnostic> {
    value
        .as_str()
        .ok_or_else(|| error("store key must be a string"))
}
fn display(value: &Value) -> String {
    value
        .as_str()
        .map(str::to_owned)
        .unwrap_or_else(|| value.to_string())
}
pub(crate) fn error(message: impl std::fmt::Display) -> CellDiagnostic {
    CellDiagnostic::new(CellDiagnosticKind::ExecutionError, message.to_string())
}
