import Metal
import MetalKit

public class OfflineRender {
    public var renderables: [Renderable] = []
    public var renderTarget: MTLTexture?

    public init() {}

    func setupRenderTarget(colorPixelFormat: MTLPixelFormat, width: Int, height: Int) {
        let descriptor = MTLTextureDescriptor()
        descriptor.textureType = .type2D
        descriptor.pixelFormat = colorPixelFormat
        descriptor.width = width
        descriptor.height = height
        descriptor.usage = [.shaderRead, .renderTarget]
        descriptor.storageMode = .private
        renderTarget = Adamantium.sharedDevice?.makeTexture(descriptor: descriptor)
    }

    public func draw(formattedTo metalView: MTKView) {
        draw(colorPixelFormat: metalView.colorPixelFormat,
             width: Int(metalView.drawableSize.width),
             height: Int(metalView.drawableSize.height))
    }

    public func draw(colorPixelFormat _: MTLPixelFormat, width _: Int, height _: Int) {
        let renderPassDescriptor = MTLRenderPassDescriptor()
        renderPassDescriptor.colorAttachments[0].texture = renderTarget
        renderPassDescriptor.colorAttachments[0].loadAction = .clear
        renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 1.0)
        renderPassDescriptor.colorAttachments[0].storeAction = .store

        guard
            let commandBuffer = Adamantium.sharedCommandQueue?.makeCommandBuffer(),
            let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor)
        else { return }

        for renderable in renderables {
            renderable.render(encoder: renderEncoder)
        }

        renderEncoder.endEncoding()
        commandBuffer.commit()
    }
}
