import Foundation

struct ToolCall: Decodable {
    struct Arguments: Decodable {
        struct Props: Decodable {
            let title: String
            let body: String
            let confirmLabel: String
            let cancelLabel: String
            let variant: String

            enum CodingKeys: String, CodingKey {
                case title, body, variant
                case confirmLabel = "confirm_label"
                case cancelLabel = "cancel_label"
            }
        }

        let id: String
        let kind: String
        let props: Props
    }

    let tool: String
    let args: Arguments
}

func escapeHTML(_ value: String) -> String {
    value
        .replacingOccurrences(of: "&", with: "&amp;")
        .replacingOccurrences(of: "<", with: "&lt;")
        .replacingOccurrences(of: ">", with: "&gt;")
        .replacingOccurrences(of: "\"", with: "&quot;")
        .replacingOccurrences(of: "'", with: "&#39;")
}

func render(_ call: ToolCall) -> String {
    precondition(call.tool == "component_render", "expected component_render")
    precondition(call.args.kind == "confirm", "expected confirm component")

    let id = escapeHTML(call.args.id)
    let props = call.args.props
    return """
    <section data-component="confirm" data-variant="\(escapeHTML(props.variant))" data-id="\(id)">
      <h3>\(escapeHTML(props.title))</h3>
      <p>\(escapeHTML(props.body))</p>
      <footer>
        <button data-action="cancel">\(escapeHTML(props.cancelLabel))</button>
        <button data-action="confirm">\(escapeHTML(props.confirmLabel))</button>
      </footer>
    </section>
    """
}

let path = CommandLine.arguments.dropFirst().first ?? "tool-call.json"
let data = try Data(contentsOf: URL(fileURLWithPath: path))
let call = try JSONDecoder().decode(ToolCall.self, from: data)
print(render(call))
