#include "codec_abstract_codec.h"
#include "codec_video_encoder.h"
#include "codec_audio_encoder.h"
#include "codec_video_decoder.h"
#include "codec_audio_decoder.h"
#include "../base/media_common.h"
#include "../base/logger.h"
#include <chrono>

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
}

namespace av {
namespace codec {

AbstractCodec::AbstractCodec(MediaType mediaType, CodecType codecType)
    : mediaType_(mediaType)
    , codecType_(codecType)
    , state_(CodecState::IDLE)
    , codec_(nullptr) {
    AV_LOGGER_DEBUGF("创建{}编解码器, 媒体类型: {}", 
                  codecType == CodecType::ENCODER ? "编码" : "解码",
                  static_cast<int>(mediaType));
}

AbstractCodec::~AbstractCodec() {
    if (state_ != CodecState::CLOSED && state_ != CodecState::IDLE) {
        AV_LOGGER_WARNING("编解码器析构时状态不正确，强制关闭");
        close();
    }
    AV_LOGGER_DEBUG("编解码器已析构");
}

ErrorCode AbstractCodec::reset() {
    AV_LOGGER_DEBUG("重置编解码器");
    
    if (state_ == CodecState::IDLE || state_ == CodecState::CLOSED) {
        return ErrorCode::SUCCESS;
    }
    
    // 先刷新缓冲区
    ErrorCode result = flush();
    if (result != ErrorCode::SUCCESS) {
        AV_LOGGER_ERRORF("刷新编解码器失败: {}", static_cast<int>(result));
        return result;
    }
    
    // 重置统计信息
    resetStatistics();
    
    setState(CodecState::OPENED);
    return ErrorCode::SUCCESS;
}

void AbstractCodec::resetStatistics() {
    std::lock_guard<std::mutex> lock(statsMutex_);
    stats_ = Statistics{};
    AV_LOGGER_DEBUG("统计信息已重置");
}

void AbstractCodec::setState(CodecState state) {
    std::unique_lock<std::shared_mutex> lock(stateMutex_);
    if (state_ != state) {
        AV_LOGGER_DEBUGF("编解码器状态变更: {} -> {}", 
                      static_cast<int>(state_), static_cast<int>(state));
        state_ = state;
    }
}

void AbstractCodec::reportError(ErrorCode error, const std::string& message) {
    setState(CodecState::ERROR);
    
    // 更新错误统计
    {
        std::lock_guard<std::mutex> lock(statsMutex_);
        stats_.errorCount++;
    }
    
    std::string fullMessage = message.empty() ? 
        ffmpeg_utils::errorToString(static_cast<int>(error)) : message;
    
    AV_LOGGER_ERRORF("编解码器错误: {} ({})", fullMessage, static_cast<int>(error));
    
    if (errorCallback_) {
        errorCallback_(error, fullMessage);
    }
}

void AbstractCodec::updateStats(bool success, double processTime, uint64_t bytes) {
    std::lock_guard<std::mutex> lock(statsMutex_);
    if (success) {
        stats_.processedFrames++;
        stats_.totalBytes += bytes;
        
        // 更新平均处理时间
        if (stats_.processedFrames == 1) {
            stats_.avgProcessTime = processTime;
        } else {
            stats_.avgProcessTime = (stats_.avgProcessTime * (stats_.processedFrames - 1) + processTime) / stats_.processedFrames;
        }
    } else {
        stats_.droppedFrames++;
    }
}

// CodecFactory 实现
std::unique_ptr<AbstractEncoder> CodecFactory::createEncoder(MediaType mediaType, const std::string& codecName) {
    AV_LOGGER_INFOF("创建编码器: {} (媒体类型: {})", codecName, static_cast<int>(mediaType));
    
    // 查找编码器
    const AVCodec* codec = avcodec_find_encoder_by_name(codecName.c_str());
    if (!codec) {
        AV_LOGGER_ERRORF("未找到编码器: {}", codecName);
        return nullptr;
    }
    
    // 检查媒体类型匹配
    AVMediaType expectedType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
    if (codec->type != expectedType) {
        AV_LOGGER_ERRORF("编码器媒体类型不匹配: {} (期望: {}, 实际: {})", 
                      codecName, expectedType, codec->type);
        return nullptr;
    }
    
    // 根据媒体类型创建具体的编码器实例
    try {
        if (mediaType == MediaType::VIDEO) {
            auto encoder = std::make_unique<VideoEncoder>();
            AV_LOGGER_INFOF("成功创建视频编码器: {}", codecName);
            return std::move(encoder);
        } else if (mediaType == MediaType::AUDIO) {
            auto encoder = std::make_unique<AudioEncoder>();
            AV_LOGGER_INFOF("成功创建音频编码器: {}", codecName);
            return std::move(encoder);
        } else {
            AV_LOGGER_ERRORF("不支持的媒体类型: {}", static_cast<int>(mediaType));
            return nullptr;
        }
    } catch (const std::exception& e) {
        AV_LOGGER_ERRORF("创建编码器实例失败: {}", e.what());
        return nullptr;
    }
}

std::unique_ptr<AbstractDecoder> CodecFactory::createDecoder(MediaType mediaType, const std::string& codecName) {
    AV_LOGGER_INFOF("创建解码器: {} (媒体类型: {})", codecName, static_cast<int>(mediaType));
    
    // 查找解码器
    const AVCodec* codec = avcodec_find_decoder_by_name(codecName.c_str());
    if (!codec) {
        AV_LOGGER_ERRORF("未找到解码器: {}", codecName);
        return nullptr;
    }
    
    // 检查媒体类型匹配
    AVMediaType expectedType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
    if (codec->type != expectedType) {
        AV_LOGGER_ERRORF("解码器媒体类型不匹配: {} (期望: {}, 实际: {})", 
                      codecName, expectedType, codec->type);
        return nullptr;
    }
    
    // 根据媒体类型创建具体的解码器实例
    try {
        if (mediaType == MediaType::VIDEO) {
            auto decoder = std::make_unique<VideoDecoder>();
            AV_LOGGER_INFOF("成功创建视频解码器: {}", codecName);
            return std::move(decoder);
        } else if (mediaType == MediaType::AUDIO) {
            auto decoder = std::make_unique<AudioDecoder>();
            AV_LOGGER_INFOF("成功创建音频解码器: {}", codecName);
            return std::move(decoder);
        } else {
            AV_LOGGER_ERRORF("不支持的媒体类型: {}", static_cast<int>(mediaType));
            return nullptr;
        }
    } catch (const std::exception& e) {
        AV_LOGGER_ERRORF("创建解码器实例失败: {}", e.what());
        return nullptr;
    }
}

std::vector<std::string> CodecFactory::getSupportedEncoders(MediaType mediaType) {
    std::vector<std::string> encoders;
    
    AVMediaType avMediaType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
    
    void* iter = nullptr;
    const AVCodec* codec = nullptr;
    
    while ((codec = av_codec_iterate(&iter)) != nullptr) {
        if (av_codec_is_encoder(codec) && codec->type == avMediaType) {
            encoders.emplace_back(codec->name);
        }
    }
    
    AV_LOGGER_INFOF("找到 {} 个{}编码器", encoders.size(), 
                 mediaType == MediaType::VIDEO ? "视频" : "音频");
    
    return encoders;
}

std::vector<std::string> CodecFactory::getSupportedDecoders(MediaType mediaType) {
    std::vector<std::string> decoders;
    
    AVMediaType avMediaType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
    
    void* iter = nullptr;
    const AVCodec* codec = nullptr;
    
    while ((codec = av_codec_iterate(&iter)) != nullptr) {
        if (av_codec_is_decoder(codec) && codec->type == avMediaType) {
            decoders.emplace_back(codec->name);
        }
    }
    
    AV_LOGGER_INFOF("找到 {} 个{}解码器", decoders.size(), 
                 mediaType == MediaType::VIDEO ? "视频" : "音频");
    
    return decoders;
}

bool CodecFactory::isCodecSupported(const std::string& codecName, CodecType type, MediaType mediaType) {
    const AVCodec* codec = nullptr;
    
    if (type == CodecType::ENCODER) {
        codec = avcodec_find_encoder_by_name(codecName.c_str());
    } else {
        codec = avcodec_find_decoder_by_name(codecName.c_str());
    }
    
    if (!codec) {
        return false;
    }
    
    AVMediaType expectedType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
    return codec->type == expectedType;
}

void AbstractCodec::close() {
    AV_LOGGER_DEBUG("关闭编解码器");
    
    // 使用RAII确保异常安全
    try {
        std::unique_lock<std::shared_mutex> stateLock(stateMutex_);
        if (state_ == CodecState::CLOSED || state_ == CodecState::IDLE) {
            return;
        }
        
        // 设置状态为关闭中，防止其他操作
        state_ = CodecState::CLOSED;
        stateLock.unlock();
        
        // 获取资源锁进行清理
        std::lock_guard<std::mutex> resourceLock(resourceMutex_);
        
        // 释放编解码上下文
        if (codecCtx_) {
            AVCodecContext* ctx = codecCtx_.release();
            avcodec_free_context(&ctx);
        }
        
        codec_ = nullptr;
        
        AV_LOGGER_DEBUG("编解码器已关闭");
        
    } catch (const std::exception& e) {
        AV_LOGGER_ERRORF("关闭编解码器时发生异常: {}", e.what());
        // 确保状态被设置为错误
        try {
            setState(CodecState::ERROR);
        } catch (...) {
            // 忽略setState可能的异常，因为我们已经在异常处理中
        }
    } catch (...) {
        AV_LOGGER_ERROR("关闭编解码器时发生未知异常");
        try {
            setState(CodecState::ERROR);
        } catch (...) {
            // 忽略setState可能的异常
        }
    }
}

ErrorCode AbstractCodec::flush() {
    AV_LOGGER_DEBUG("刷新编解码器缓冲区");
    
    if (state_ != CodecState::OPENED && state_ != CodecState::RUNNING) {
        AV_LOGGER_WARNING("编解码器未打开，无法刷新");
        return ErrorCode::INVALID_STATE;
    }
    
    if (!codecCtx_) {
        AV_LOGGER_ERROR("编解码上下文为空");
        return ErrorCode::INVALID_STATE;
    }
    
    // 刷新编解码器
    avcodec_flush_buffers(codecCtx_.get());
    
    AV_LOGGER_DEBUG("编解码器缓冲区已刷新");
    return ErrorCode::SUCCESS;
}

// 错误码转换工具实现
ErrorCode AbstractCodec::convertFFmpegError(int ffmpegError) {
    if (ffmpegError >= 0) {
        return ErrorCode::SUCCESS;
    }
    
    // 根据FFmpeg错误码映射到项目中已定义的错误码
    switch (ffmpegError) {
        case AVERROR(EINVAL):
            return ErrorCode::INVALID_PARAMS;
        case AVERROR(ENOMEM):
            return ErrorCode::MEMORY_ALLOC_FAILED;
        case AVERROR(EAGAIN):
            return ErrorCode::PROCESSING_ERROR;  // 使用PROCESSING_ERROR代替RESOURCE_BUSY
        case AVERROR_EOF:
            return ErrorCode::END_OF_STREAM;
        case AVERROR(ENOSYS):
            return ErrorCode::NOT_SUPPORTED;
        case AVERROR(EPIPE):
            return ErrorCode::OPERATION_FAILED;  // 使用OPERATION_FAILED代替BROKEN_PIPE
        case AVERROR(EIO):
            return ErrorCode::FILE_OPERATION_FAILED;  // 使用FILE_OPERATION_FAILED代替IO_ERROR
        case AVERROR(EACCES):
            return ErrorCode::FILE_OPEN_FAILED;  // 使用FILE_OPEN_FAILED代替ACCESS_DENIED
        case AVERROR_DECODER_NOT_FOUND:
            return ErrorCode::CODEC_NOT_FOUND;  // 使用CODEC_NOT_FOUND代替DECODER_NOT_FOUND
        case AVERROR_ENCODER_NOT_FOUND:
            return ErrorCode::CODEC_NOT_FOUND;  // 使用CODEC_NOT_FOUND代替ENCODER_NOT_FOUND
        case AVERROR_DEMUXER_NOT_FOUND:
            return ErrorCode::NOT_FOUND;  // 使用通用NOT_FOUND
        case AVERROR_MUXER_NOT_FOUND:
            return ErrorCode::NOT_FOUND;  // 使用通用NOT_FOUND
        case AVERROR_PROTOCOL_NOT_FOUND:
            return ErrorCode::NOT_FOUND;  // 使用通用NOT_FOUND
        case AVERROR_STREAM_NOT_FOUND:
            return ErrorCode::STREAM_NOT_FOUND;
        case AVERROR_BUG:
            return ErrorCode::UNKNOWN_ERROR;  // 使用UNKNOWN_ERROR代替INTERNAL_ERROR
        case AVERROR_UNKNOWN:
            return ErrorCode::UNKNOWN_ERROR;
        case AVERROR_EXPERIMENTAL:
            return ErrorCode::NOT_SUPPORTED;
        case AVERROR_INPUT_CHANGED:
            return ErrorCode::FORMAT_NOT_SUPPORTED;  // 使用FORMAT_NOT_SUPPORTED代替FORMAT_CHANGED
        case AVERROR_OUTPUT_CHANGED:
            return ErrorCode::FORMAT_NOT_SUPPORTED;  // 使用FORMAT_NOT_SUPPORTED代替FORMAT_CHANGED
        case AVERROR_BSF_NOT_FOUND:
            return ErrorCode::NOT_FOUND;  // 使用通用NOT_FOUND代替FILTER_NOT_FOUND
        case AVERROR_BUG2:
            return ErrorCode::UNKNOWN_ERROR;  // 使用UNKNOWN_ERROR代替INTERNAL_ERROR
        case AVERROR_BUFFER_TOO_SMALL:
            return ErrorCode::MEMORY_ALLOC_FAILED;  // 使用MEMORY_ALLOC_FAILED代替BUFFER_TOO_SMALL
        case AVERROR_EXTERNAL:
            return ErrorCode::OPERATION_FAILED;  // 使用OPERATION_FAILED代替EXTERNAL_ERROR
        case AVERROR_INVALIDDATA:
            return ErrorCode::INVALID_PARAMS;  // 使用INVALID_PARAMS代替INVALID_DATA
        case AVERROR_PATCHWELCOME:
            return ErrorCode::NOT_SUPPORTED;  // 使用NOT_SUPPORTED代替NOT_IMPLEMENTED
        default:
            // 对于未映射的错误，记录原始错误码
            AV_LOGGER_WARNING("未映射的FFmpeg错误码，使用通用错误");
            return ErrorCode::UNKNOWN_ERROR;
    }
}

std::string AbstractCodec::getErrorDescription(ErrorCode error) {
    switch (error) {
        case ErrorCode::SUCCESS:
            return "成功";
        case ErrorCode::INVALID_PARAMS:
            return "无效参数";
        case ErrorCode::INVALID_PATH:
            return "无效路径";
        case ErrorCode::CODEC_NOT_FOUND:
            return "编解码器未找到";
        case ErrorCode::CODEC_OPEN_FAILED:
            return "编解码器打开失败";
        case ErrorCode::ENCODE_FAILED:
            return "编码失败";
        case ErrorCode::DECODE_FAILED:
            return "解码失败";
        case ErrorCode::MEMORY_ALLOC_FAILED:
            return "内存分配失败";
        case ErrorCode::FILE_OPEN_FAILED:
            return "文件打开失败";
        case ErrorCode::FILE_EXISTS:
            return "文件已存在";
        case ErrorCode::FILE_OPERATION_FAILED:
            return "文件操作失败";
        case ErrorCode::INVALID_STATE:
            return "无效状态";
        case ErrorCode::NOT_STARTED:
            return "未开始";
        case ErrorCode::NOT_PAUSED:
            return "未暂停";
        case ErrorCode::ALREADY_INITIALIZED:
            return "已经初始化";
        case ErrorCode::NOT_INITIALIZED:
            return "未初始化";
        case ErrorCode::ALREADY_STARTED:
            return "已经开始";
        case ErrorCode::ALREADY_PAUSED:
            return "已经暂停";
        case ErrorCode::CONVERSION_FAILED:
            return "转换失败";
        case ErrorCode::FORMAT_NOT_SUPPORTED:
            return "格式不支持";
        case ErrorCode::NOT_SUPPORTED:
            return "不支持的操作";
        case ErrorCode::HARDWARE_ERROR:
            return "硬件错误";
        case ErrorCode::DEVICE_NOT_FOUND:
            return "设备未找到";
        case ErrorCode::STREAM_NOT_FOUND:
            return "流未找到";
        case ErrorCode::STREAM_EXISTS:
            return "流已存在";
        case ErrorCode::STREAM_CREATE_FAILED:
            return "流创建失败";
        case ErrorCode::END_OF_STREAM:
            return "流结束";
        case ErrorCode::THREAD_ERROR:
            return "线程错误";
        case ErrorCode::QUEUE_FULL:
            return "队列满";
        case ErrorCode::SYNC_ERROR:
            return "同步错误";
        case ErrorCode::ALREADY_EXISTS:
            return "已存在";
        case ErrorCode::NOT_FOUND:
            return "未找到";
        case ErrorCode::TIMEOUT:
            return "超时";
        case ErrorCode::COPY_FAILED:
            return "拷贝失败";
        case ErrorCode::PROCESSING_ERROR:
            return "处理错误";
        case ErrorCode::INITIALIZATION_FAILED:
            return "初始化失败";
        case ErrorCode::OPERATION_FAILED:
            return "操作失败";
        case ErrorCode::UNKNOWN_ERROR:
            return "未知错误";
        default:
            return "未知错误码: " + std::to_string(static_cast<int>(error));
    }
}

} // namespace codec
} // namespace av