package org.kne.codec.kif;

import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;

import org.kne.debug.TimeDebugger;

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.IOException;
import java.lang.foreign.MemorySegment;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicReference;

/**
 * KIF格式的实际解码器。
 * 这个类负责读取.kif文件并解码成BufferedImage。
 */
public class KIFImageReader extends ImageReader {

    private ImageInputStream inputStream;
    private int width = -1;
    private int height = -1;

    protected KIFImageReader(ImageReaderSpi originatingProvider) {
        super(originatingProvider);
    }

    @Override
    public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
        super.setInput(input, seekForwardOnly, ignoreMetadata);
        if (input instanceof ImageInputStream) {
            this.inputStream = (ImageInputStream) input;
        } else {
            this.inputStream = null;
        }
        // 重置状态
        this.width = -1;
        this.height = -1;
    }

    /**
     * 读取文件头，获取图像尺寸等元数据
     */
    private void readHeader() throws IOException {
        if (inputStream == null) {
            throw new IllegalStateException("Input not set");
        }


            // 文件头结构（你需要根据实际格式调整）：
            // Magic: 3 bytes "KIF"
            // Version: 1 byte
            // Width: 4 bytes (int)
            // Height: 4 bytes (int)
            // 更多元数据...
            
        	// 校验魔数 (已由Spi验证，但外部直接调用时仍需防御)
        	byte[] magic = new byte[3];
        	inputStream.readFully(magic);
        	if (magic[0] != 0x4B || magic[1] != 0x49 || magic[2] != 0x46) {
        	    throw new IOException("无效的 KIF 文件格式: 魔数不匹配 (期望 KIF, 实际 " +
        	        String.format("%02X %02X %02X", magic[0], magic[1], magic[2]) + ")");
        	}
            
            // 读取版本
            byte version = inputStream.readByte();

            // 读取类型
            byte type = inputStream.readByte();
            
            // 读取宽高 (假设为大端序)
            this.width = inputStream.readInt();
            this.height = inputStream.readInt();
            
            // 这里可以读取更多元数据，例如预测模式、压缩方式等
            
    }

    @Override
    public int getWidth(int imageIndex) throws IOException {
        if (imageIndex != 0) {
            throw new IndexOutOfBoundsException("Only image index 0 is supported");
        }
        readHeader();
        return width;
    }

    @Override
    public int getHeight(int imageIndex) throws IOException {
        if (imageIndex != 0) {
            throw new IndexOutOfBoundsException("Only image index 0 is supported");
        }
        readHeader();
        return height;
    }

    @Override
    public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException {
        if (imageIndex != 0) {
            throw new IndexOutOfBoundsException("Only image index 0 is supported");
        }
        readHeader();
        
        // 返回支持的图像类型（这里只支持标准的RGB或灰度）
        List<ImageTypeSpecifier> types = new ArrayList<>();
        
        // 支持 RGB (8-bit interleaved)
        types.add(ImageTypeSpecifier.createInterleaved(
            java.awt.color.ColorSpace.getInstance(java.awt.color.ColorSpace.CS_sRGB),
            new int[]{0, 1, 2}, // band offsets: R, G, B
            0, // data type: TYPE_BYTE
            false, // hasAlpha
            false // isAlphaPremultiplied
        ));
        
        // 支持灰度
        types.add(ImageTypeSpecifier.createGrayscale(8, 0, false));
        
        return types.iterator();
    }

    @Override
    public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException {
        if (imageIndex != 0) {
            throw new IndexOutOfBoundsException("Only image index 0 is supported");
        }
        TimeDebugger tdb=new TimeDebugger("读取时间",false);
        readHeader();

        tdb.mark("读取文件头");
        AtomicReference<int[]>array=new AtomicReference<>();
        int blockcount=inputStream.readInt();
           ArrayList<Future<IntImageBlock>>decodeing=new ArrayList<>(blockcount);
           KIFCodec.backPressure();
       for(int i=0;i<blockcount;i++) {
           	decodeing.add( KIFCodec.decodeAndConsumeAsync(()->{
    			KIFCompressedImageBlock kip;
    			synchronized (inputStream) {
    				try {
						kip=KIFCompressedImageBlock.readFromStream(inputStream);
					} catch (IOException e) {
						throw new RuntimeException(e);
					}
    				}
    			return kip;
    		},(out)->{
           		while(array.get()==null) {
           			Thread.yield();
           		}
           		out.toImage(MemorySegment.ofArray( array.get()), width, height);
           	}));
       }

        tdb.mark("读取文件并提交解码");

       
        BufferedImage image =BufferedImageMembandBoost.createUninitializedBufferedImage(width, height);
        int[] dest = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
        array.set(dest);
        tdb.mark("分配输出图像内存");
        for(Future<IntImageBlock> compressed:decodeing) {
        	try {
				compressed.get();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				ExceptionTool.throwIOException(e);
			}
        }
        
        tdb.mark("解码/拼接");
        tdb.print();
        return image;
    }

    @Override
    public IIOMetadata getStreamMetadata() throws IOException {
        return null; // 本实现不提供流元数据
    }

    @Override
    public IIOMetadata getImageMetadata(int imageIndex) throws IOException {
        return null; // 本实现不提供图像元数据
    }

    @Override
    public int getNumImages(boolean allowSearch) throws IOException {
        return 1; // KIF格式只包含单张图像（文件版本）
    }

    @Override
    public void dispose() {
      
        super.dispose();
    }
}