import XCTest
import CoreGraphics
import ImageIO
@testable import PoseCore

final class InspectionRendererTests: XCTestCase {
    func testJointIDsStayStableAcrossMissingJointsAndPoseKinds() {
        XCTAssertEqual(InspectionRenderer.jointID("right_wrist"), 11)
        XCTAssertEqual(InspectionRenderer.jointID("right_knee"), 16)
        XCTAssertEqual(Set(InspectionRenderer.jointNames).count, InspectionRenderer.jointNames.count)
        XCTAssertNil(InspectionRenderer.jointID("unknown"))
    }

    func testLegendExtendsCanvasWithoutMovingSourcePixels() throws {
        let source = CGContext(data: nil, width: 120, height: 80, bitsPerComponent: 8, bytesPerRow: 0,
                               space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!
        source.setFillColor(CGColor(red: 1, green: 0, blue: 0, alpha: 1))
        source.fill(CGRect(x: 0, y: 0, width: 120, height: 80))
        source.setFillColor(CGColor(red: 0, green: 0, blue: 1, alpha: 1))
        source.fill(CGRect(x: 0, y: 0, width: 60, height: 40))
        let image = source.makeImage()!
        let pose = PoseResult(kind: "2D", status: "noPose", requestRevision: 1, durationSeconds: 0,
                              joints: [], candidateCount: 0)
        let url = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString + ".png")
        defer { try? FileManager.default.removeItem(at: url) }
        try InspectionRenderer.write(image: image, panel: PixelRect(x: 100, y: 50, width: 120, height: 80),
                                     crop: PixelRect(x: 100, y: 50, width: 120, height: 80), pose: pose, annotations: [], url: url)
        let output = CGImageSourceCreateImageAtIndex(CGImageSourceCreateWithURL(url as CFURL, nil)!, 0, nil)!
        XCTAssertGreaterThan(output.width, image.width)
        XCTAssertGreaterThanOrEqual(output.height, 500)
        // Read the exported top-left photo area through a known RGBA context.
        let sample = CGContext(data: nil, width: output.width, height: output.height, bitsPerComponent: 8, bytesPerRow: output.width * 4,
                               space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!
        sample.draw(output, in: CGRect(x: 0, y: 0, width: output.width, height: output.height))
        let bytes = sample.data!.assumingMemoryBound(to: UInt8.self)
        let baseline = CGContext(data: nil, width: 120, height: 80, bitsPerComponent: 8, bytesPerRow: 120 * 4,
                                 space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!
        baseline.draw(image, in: CGRect(x: 0, y: 0, width: 120, height: 80))
        let original = baseline.data!.assumingMemoryBound(to: UInt8.self)
        for y in [20, 60] {
            for x in [20, 100] {
                for channel in 0..<4 {
                    XCTAssertEqual(Int(bytes[(y * output.width + x) * 4 + channel]),
                                   Int(original[(y * 120 + x) * 4 + channel]), accuracy: 1)
                }
            }
        }
    }
}
