package org.kne.codec.kvf;

import org.jcodec.common.DemuxerTrack;
import org.jcodec.common.DemuxerTrackMeta;
import org.jcodec.common.io.NIOUtils;
import org.jcodec.common.io.SeekableByteChannel;
import org.jcodec.common.model.Packet;
import org.jcodec.common.model.Picture;
import org.jcodec.common.model.Size;
import org.jcodec.containers.mp4.MP4TrackType;
import org.jcodec.containers.mp4.boxes.*;
import org.jcodec.containers.mp4.demuxer.AbstractMP4DemuxerTrack;
import org.jcodec.containers.mp4.demuxer.MP4Demuxer;
import org.jcodec.containers.mp4.demuxer.MP4DemuxerTrack;

import java.io.File;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * MP4 元数据分析器
 * 获取音视频轨道、帧率、GOP、编码格式等完整元数据
 */
public class MP4Analyzer {

    public static void main(String[] args) throws Exception {
        System.setOut(new PrintStream(System.out, true, StandardCharsets.UTF_8));
        System.setErr(new PrintStream(System.err, true, StandardCharsets.UTF_8));
        if (args.length < 1) {
            System.err.println("用法: java MP4Analyzer <video.mp4>");
            System.exit(1);
        }

        File file = new File(args[0]);
        if (!file.exists()) {
            System.err.println("文件不存在: " + file.getAbsolutePath());
            System.exit(1);
        }

        System.out.println("========================================");
        System.out.println("📹 MP4 元数据分析: " + file.getName());
        System.out.println("========================================\n");

        try (SeekableByteChannel channel = NIOUtils.readableChannel(file);
             MP4Demuxer demuxer = MP4Demuxer.createMP4Demuxer(channel)) {

            // 1. 视频轨道信息
            analyzeVideoTrack(demuxer);

            // 2. 音频轨道信息
            analyzeAudioTracks(demuxer);

            // 3. 其他轨道
            analyzeOtherTracks(demuxer);

            // 4. 容器元数据
            analyzeContainerInfo(demuxer);

            // 5. GOP 结构分析
            analyzeGOP(demuxer);

            // 6. 统计信息
            printSummary(demuxer);
        }
    }

    /**
     * 分析视频轨道
     */
    private static void analyzeVideoTrack(MP4Demuxer demuxer) throws Exception {
        System.out.println("🎬 视频轨道 (Video Tracks)");
        System.out.println("───────────────────────────────────────────────");

        List<DemuxerTrack> videoTracks = demuxer.getVideoTracks();
        if (videoTracks.isEmpty()) {
            System.out.println("  ❌ 无视频轨道");
            System.out.println();
            return;
        }

        for (int i = 0; i < videoTracks.size(); i++) {
            DemuxerTrack track = videoTracks.get(i);
            DemuxerTrackMeta meta = track.getMeta();

            System.out.printf("  轨道 %d:\n", i);
            System.out.printf("    编码格式: %s\n", meta.getCodec());
            System.out.printf("    分辨率: %dx%d\n", meta.getVideoCodecMeta().getSize().getWidth(),
                    meta.getVideoCodecMeta().getSize().getHeight());
            System.out.printf("    帧率: %.3f fps\n", meta.getTotalFrames() / meta.getTotalDuration());
            System.out.printf("    总帧数: %d\n", meta.getTotalFrames());
            System.out.printf("    时长: %.2f 秒\n", meta.getTotalDuration());
            System.out.printf("    像素格式: %s\n", meta.getVideoCodecMeta().getColor());
           // System.out.printf("    参考帧数: %d\n", meta.getVideoCodecMeta().getRefFrames());
           // System.out.printf("    是否可变帧率: %s\n", meta.isVariableFps() ? "是" : "否");

            // 尝试获取更多信息
            if (track instanceof MP4DemuxerTrack) {
                MP4DemuxerTrack m4Track = (MP4DemuxerTrack) track;
             //   System.out.printf("    轨道 ID: %d\n", m4Track.getTrackId());
                System.out.printf("    轨道类型: %s\n", m4Track.getType());
            }

            System.out.println();
        }
    }

    /**
     * 分析音频轨道
     */
    private static void analyzeAudioTracks(MP4Demuxer demuxer) {
        System.out.println("🎵 音频轨道 (Audio Tracks)");
        System.out.println("───────────────────────────────────────────────");

        List<DemuxerTrack> audioTracks = demuxer.getAudioTracks();
        if (audioTracks.isEmpty()) {
            System.out.println("  ❌ 无音频轨道");
            System.out.println();
            return;
        }

        for (int i = 0; i < audioTracks.size(); i++) {
            DemuxerTrack track = audioTracks.get(i);
            DemuxerTrackMeta meta = track.getMeta();

            System.out.printf("  轨道 %d:\n", i);
            System.out.printf("    编码格式: %s\n", meta.getCodec());
            System.out.printf("    采样率: %d Hz\n", meta.getAudioCodecMeta().getSampleRate());
            System.out.printf("    声道数: %d\n", meta.getAudioCodecMeta().getChannelCount());
            System.out.printf("    采样位数: %d bit\n", meta.getAudioCodecMeta().getSampleSize());
            System.out.printf("    总帧数: %d\n", meta.getTotalFrames());
            System.out.printf("    时长: %.2f 秒\n", meta.getTotalDuration());
            System.out.println();
        }
    }

    /**
     * 分析其他轨道（字幕等）
     */
    private static void analyzeOtherTracks(MP4Demuxer demuxer) {
        System.out.println("📝 其他轨道 (Other Tracks)");
        System.out.println("───────────────────────────────────────────────");

        List<AbstractMP4DemuxerTrack> otherTracks = demuxer.getTracks();
        if (otherTracks.isEmpty()) {
            System.out.println("  ❌ 无其他轨道");
            System.out.println();
            return;
        }

        for (DemuxerTrack track : otherTracks) {
            DemuxerTrackMeta meta = track.getMeta();
            System.out.printf("  轨道类型: %s, 编码: %s\n",
                    meta.getCodec(), meta.getCodec());
        }
        System.out.println();
    }

    /**
     * 分析容器元数据
     */
    private static void analyzeContainerInfo(MP4Demuxer demuxer) {
        System.out.println("📦 容器信息 (Container Info)");
        System.out.println("───────────────────────────────────────────────");

        // 获取 FileTypeBox (ftyp)
      /*  FileTypeBox ftyp = demuxer.getBoxes(FileTypeBox.class).get(0);
        System.out.printf("  主要品牌: %s\n", ftyp.getMajorBrand());
        System.out.printf("  兼容品牌: %s\n", String.join(", ", ftyp.getCompatibleBrands()));
        System.out.printf("  版本: %d\n", ftyp.getVersion());
*/
        // 获取 MovieBox (moov)
        MovieBox moov = demuxer.getMovie();
        System.out.printf("  时长 (timescale): %d\n", moov.getTimescale());
        System.out.println();
    }

    /**
     * 分析 GOP 结构
     */
    private static void analyzeGOP(MP4Demuxer demuxer) throws Exception {
        System.out.println("🎯 GOP 结构分析 (GOP Structure)");
        System.out.println("───────────────────────────────────────────────");

        List<DemuxerTrack> videoTracks = demuxer.getVideoTracks();
        if (videoTracks.isEmpty()) {
            System.out.println("  ❌ 无视频轨道");
            System.out.println();
            return;
        }

        DemuxerTrack videoTrack = videoTracks.get(0);
        DemuxerTrackMeta meta = videoTrack.getMeta();

        // 获取 I 帧位置
        int[] seekFrames = meta.getSeekFrames();
        if (seekFrames == null || seekFrames.length == 0) {
            System.out.println("  ⚠️ 无法获取 I 帧位置");
            System.out.println();
            return;
        }

        System.out.printf("  I 帧数量: %d\n", seekFrames.length);
        System.out.printf("  平均 GOP 大小: %.1f 帧\n",
                (double) meta.getTotalFrames() / seekFrames.length);

        // 显示前 10 个 GOP
        System.out.println("  前 10 个 I 帧位置:");
        for (int i = 0; i < Math.min(10, seekFrames.length); i++) {
            int nextIFrame = (i + 1 < seekFrames.length) ? seekFrames[i + 1] : meta.getTotalFrames();
            int gopSize = nextIFrame - seekFrames[i];
            System.out.printf("    GOP %d: I 帧位置 %d, GOP 大小 %d 帧\n",
                    i, seekFrames[i], gopSize);
        }

        // 检查是否有 B 帧
        boolean hasBFrame = false;
        try {
            // 重置轨道位置
            // 读取前 100 帧判断
            // 这里简化判断
        } catch (Exception e) {
            // 忽略
        }
        System.out.println();
    }

    /**
     * 打印统计摘要
     */
    private static void printSummary(MP4Demuxer demuxer) {
        System.out.println("📊 统计摘要");
        System.out.println("───────────────────────────────────────────────");

        List<DemuxerTrack> videoTracks = demuxer.getVideoTracks();
        List<DemuxerTrack> audioTracks = demuxer.getAudioTracks();

        System.out.printf("  视频轨道: %d\n", videoTracks.size());
        System.out.printf("  音频轨道: %d\n", audioTracks.size());

        if (!videoTracks.isEmpty()) {
            DemuxerTrackMeta meta = videoTracks.get(0).getMeta();
            System.out.printf("  视频编码: %s\n", meta.getCodec());
            Size size = meta.getVideoCodecMeta().getSize();
            System.out.printf("  分辨率: %dx%d\n", size.getWidth(), size.getHeight());
            System.out.printf("  帧率: %.3f fps\n", meta.getTotalFrames() / meta.getTotalDuration());
            System.out.printf("  总帧数: %d\n", meta.getTotalFrames());
            System.out.printf("  时长: %.2f 秒 (%.2f 分钟)\n",
                    meta.getTotalDuration(), meta.getTotalDuration() / 60.0);

            int[] seekFrames = meta.getSeekFrames();
            if (seekFrames != null) {
                System.out.printf("  GOP 数量: %d\n", seekFrames.length);
                System.out.printf("  平均 GOP 大小: %.1f 帧\n",
                        (double) meta.getTotalFrames() / seekFrames.length);
            }
        }

        if (!audioTracks.isEmpty()) {
            DemuxerTrackMeta meta = audioTracks.get(0).getMeta();
            System.out.printf("  音频编码: %s\n", meta.getCodec());
            System.out.printf("  采样率: %d Hz\n", meta.getAudioCodecMeta().getSampleRate());
            System.out.printf("  声道数: %d\n", meta.getAudioCodecMeta().getChannelCount());
        }

        System.out.println();
        System.out.println("✅ 分析完成！");
    }
}