//
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//

import Foundation
import SignalCoreKit

public struct EncryptedFileHandleImageSource: OWSImageSource {

    private let fileHandle: EncryptedFileHandle

    public init(fileHandle: EncryptedFileHandle) {
        self.fileHandle = fileHandle
    }

    public init(
        encryptedFileUrl: URL,
        encryptionKey: Data,
        plaintextLength: UInt32
    ) throws {
        let fileHandle = try Cryptography.encryptedAttachmentFileHandle(
            at: encryptedFileUrl,
            plaintextLength: plaintextLength,
            encryptionKey: encryptionKey
        )
        self.init(fileHandle: fileHandle)
    }

    public var byteLength: Int { return Int(fileHandle.plaintextLength) }

    public func readData(byteOffset: Int, byteLength: Int) throws -> Data {
        if fileHandle.offset() != byteOffset {
            try fileHandle.seek(toOffset: UInt32(byteOffset))
        }
        return try fileHandle.read(upToCount: UInt32(byteLength))
    }

    public func readIntoMemory() throws -> Data {
        if fileHandle.offset() != 0 {
            try fileHandle.seek(toOffset: 0)
        }
        return try fileHandle.read(upToCount: fileHandle.plaintextLength)
    }

    // Class-bound wrapper around FileHandle
    class FileHandleWrapper {
        let fileHandle: FileHandle

        init(_ fileHandle: FileHandle) {
            self.fileHandle = fileHandle
        }
    }

    public func cgImageSource() throws -> CGImageSource? {
        let dataProvider = try CGDataProvider.from(fileHandle: fileHandle)
        return CGImageSourceCreateWithDataProvider(dataProvider, nil)
    }
}
