package org.kne.codec.kif;

import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 字节统计收集器
 * 统计 byte[] 中不同字节值的出现次数与概率（0~255）
 * 
 * 用于分析像素数据、残差数据、位平面数据的分布特性
 */
public class ByteStatisticsCollector extends StatisticsCollector<Byte> {
    
    private static final ByteFormatter FORMATTER = new ByteFormatter();
    
    /**
     * 统计整个字节数组
     */
    public void analyze(byte[] data) {
        for (byte b : data) {
            addRecord(b);
        }
    }
    
    /**
     * 统计字节数组的指定范围
     */
    public void analyze(byte[] data, int offset, int length) {
        int end = Math.min(offset + length, data.length);
        for (int i = offset; i < end; i++) {
            addRecord(data[i]);
        }
    }
    
    /**
     * 统计后返回最常见的字节值
     */
    public byte getMostCommonByte() {
        Map<Byte, AtomicLong> sorted = getSorted();
        if (sorted.isEmpty()) {
            return 0;
        }
        return sorted.entrySet().iterator().next().getKey();
    }
    
    /**
     * 统计后返回最常见字节值的出现次数
     */
    public long getMostCommonCount() {
        Map<Byte, AtomicLong> sorted = getSorted();
        if (sorted.isEmpty()) {
            return 0;
        }
        return sorted.entrySet().iterator().next().getValue().get();
    }
    
    /**
     * 统计后返回最常见字节值的占比（百分比）
     */
    public double getMostCommonProbability() {
        byte mostCommon = getMostCommonByte();
        return getProbability(mostCommon);
    }
    
    /**
     * 获取字节值对应的可读字符串
     */
    public String byteToString(byte b) {
        int v = b & 0xFF;
        return String.format("0x%02X (%d)", v, v);
    }
    
    /**
     * 生成字节统计的表格报告
     */
    @Override
    public String toString() {
        return formatTable(FORMATTER);
    }
    
    /**
     * 生成 CSV 报告
     */
    public String toCSV() {
        return super.toCSV(FORMATTER);
    }
    
    /**
     * Byte 格式化器
     */
    private static class ByteFormatter implements ItemFormatter<Byte> {
        @Override
        public String format(Byte item) {
            int v = item & 0xFF;
            return String.format("0x%02X", v);
        }
    }
}