import com.fasterxml.jackson.databind.ObjectMapper
import java.nio.file.Files
import java.nio.file.Paths
import java.awt.image.BufferedImage
import javax.imageio.ImageIO
import java.io.ByteArrayOutputStream

def API_KEY = "your API key"
def FILE_TO_UPLOAD = "/path/to/file/name.tif"
def DESIRED_FILENAME = "name.tif"
def DESIRED_FOLDER = "your folder name"
def URL_STRING = "https://app.biodock.ai/api/external/filesystem-items/upload-file"

def boundary = "----Boundary${System.currentTimeMillis()}"

def filePath = Paths.get(FILE_TO_UPLOAD)
if (!Files.exists(filePath)) {
    println("File not found: $FILE_TO_UPLOAD")
    return
}

// File extension in lowercase
def extension = DESIRED_FILENAME.substring(DESIRED_FILENAME.lastIndexOf('.') + 1).toLowerCase()

// A helper function to map common extensions to ImageIO formats
def getImageFormatForExtension(ext) {
    switch (ext) {
        case "jpg":
        case "jpeg":
            return "JPEG"
        case "png":
            return "PNG"
        case "bmp":
            return "BMP"
        case "gif":
            return "GIF"
        case "wbmp":
            return "WBMP"
        case "tif":
        case "tiff":
            return "TIFF"
        default:
            // If unknown, default to PNG or consider error handling
            return "PNG"
    }
}

// Read the image
def originalImage = ImageIO.read(filePath.toFile())
if (originalImage == null) {
    println("Could not read the image from the provided file path.")
    return
}

def hasAlpha = originalImage.colorModel.hasAlpha()
BufferedImage imageToUpload
String formatToWrite

if (hasAlpha) {
    // RGBA case
    println("Image has alpha channel. Converting to RGB...")
    def width = originalImage.width
    def height = originalImage.height
    imageToUpload = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB)
    def g = imageToUpload.createGraphics()
    g.drawImage(originalImage, 0, 0, null)
    g.dispose()
    
    // Choose TIFF or PNG based on extension
    if (extension == "tif" || extension == "tiff") {
        formatToWrite = "TIFF"
    } else {
        formatToWrite = "PNG"
    }
} else {
    // RGB case: use original format
    imageToUpload = originalImage
    formatToWrite = getImageFormatForExtension(extension)
}

// Convert the final image to a byte array
def baos = new ByteArrayOutputStream()
if (!ImageIO.write(imageToUpload, formatToWrite, baos)) {
    println("Failed to write image with format: $formatToWrite. Consider changing the format or installing required plugins.")
    return
}
baos.flush()
def fileBytes = baos.toByteArray()
baos.close()

// Create and send POST request
def conn = new URL(URL_STRING).openConnection() as HttpURLConnection
conn.requestMethod = "POST"
conn.setRequestProperty("X-API-KEY", API_KEY)
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=$boundary")
conn.doOutput = true

conn.outputStream.withWriter("UTF-8") { w ->
    w.write("--$boundary\r\n")
    w.write('Content-Disposition: form-data; name="fileName"\r\n\r\n')
    w.write("$DESIRED_FILENAME\r\n")

    w.write("--$boundary\r\n")
    w.write('Content-Disposition: form-data; name="destinationFolder"\r\n\r\n')
    w.write("$DESIRED_FOLDER\r\n")

    w.write("--$boundary\r\n")
    w.write('Content-Disposition: form-data; name="upload"; filename="' + DESIRED_FILENAME + '"\r\n')
    w.write("Content-Type: application/octet-stream\r\n\r\n")
    w.flush()

    conn.outputStream.write(fileBytes)
    w.write("\r\n--$boundary--\r\n")
    w.flush()
}

def responseCode = conn.responseCode
def responseText = (responseCode >= 200 && responseCode < 300) ? conn.inputStream.text : conn.errorStream?.text
println(responseText)

try {
    def data = new ObjectMapper().readValue(responseText, Map)
    data.each { k, v -> println("${k}: ${v}") }
} catch (ignore) {
    // Ignore if data is not JSON or cannot be parsed
}
