#include "media_common.h"
#include "logger.h"
#include <algorithm>
#include <sstream>
#include <fstream>
#include <filesystem>
#include <cctype>
#include <iomanip>
#include <cstring>
#include <limits>

// FFmpeg头文件
extern "C" {
#include <libavutil/avutil.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libswresample/swresample.h>
#include <libavutil/log.h>
#include <libavutil/error.h>
#include <libavutil/pixfmt.h>
#include <libavutil/pixdesc.h>
#include <libavutil/samplefmt.h>
#include <libavutil/frame.h>
#include <libavcodec/packet.h>
}

namespace av {

// 字符串工具实现
namespace string_utils {

std::vector<std::string> split(const std::string& str, char delimiter) {
    std::vector<std::string> result;
    std::stringstream ss(str);
    std::string item;
    
    while (std::getline(ss, item, delimiter)) {
        result.push_back(item);
    }
    
    return result;
}

std::vector<std::string> split(const std::string& str, const std::string& delimiter) {
    std::vector<std::string> result;
    size_t start = 0;
    size_t end = str.find(delimiter);
    
    while (end != std::string::npos) {
        result.push_back(str.substr(start, end - start));
        start = end + delimiter.length();
        end = str.find(delimiter, start);
    }
    
    result.push_back(str.substr(start));
    return result;
}

std::string trim(const std::string& str) {
    return trimLeft(trimRight(str));
}

std::string trimLeft(const std::string& str) {
    auto start = str.begin();
    while (start != str.end() && std::isspace(*start)) {
        start++;
    }
    return std::string(start, str.end());
}

std::string trimRight(const std::string& str) {
    auto end = str.end();
    while (end != str.begin() && std::isspace(*(end - 1))) {
        end--;
    }
    return std::string(str.begin(), end);
}

std::string replace(const std::string& str, const std::string& from, const std::string& to) {
    std::string result = str;
    size_t pos = 0;
    
    while ((pos = result.find(from, pos)) != std::string::npos) {
        result.replace(pos, from.length(), to);
        pos += to.length();
    }
    
    return result;
}

std::string toLower(const std::string& str) {
    std::string result = str;
    std::transform(result.begin(), result.end(), result.begin(), ::tolower);
    return result;
}

std::string toUpper(const std::string& str) {
    std::string result = str;
    std::transform(result.begin(), result.end(), result.begin(), ::toupper);
    return result;
}

bool startsWith(const std::string& str, const std::string& prefix) {
    return str.length() >= prefix.length() && 
           str.compare(0, prefix.length(), prefix) == 0;
}

bool endsWith(const std::string& str, const std::string& suffix) {
    return str.length() >= suffix.length() && 
           str.compare(str.length() - suffix.length(), suffix.length(), suffix) == 0;
}

bool contains(const std::string& str, const std::string& substr) {
    return str.find(substr) != std::string::npos;
}

} // namespace string_utils

// 文件路径工具实现
namespace path_utils {

std::string join(const std::string& path1, const std::string& path2) {
    if (path1.empty()) return path2;
    if (path2.empty()) return path1;
    
    std::filesystem::path p1(path1);
    std::filesystem::path p2(path2);
    return (p1 / p2).string();
}

std::string getDirectory(const std::string& path) {
    std::filesystem::path p(path);
    return p.parent_path().string();
}

std::string getFilename(const std::string& path) {
    std::filesystem::path p(path);
    return p.filename().string();
}

std::string getExtension(const std::string& path) {
    std::filesystem::path p(path);
    return p.extension().string();
}

std::string removeExtension(const std::string& path) {
    std::filesystem::path p(path);
    return p.replace_extension().string();
}

std::string normalize(const std::string& path) {
    std::filesystem::path p(path);
    return std::filesystem::weakly_canonical(p).string();
}

std::string toNative(const std::string& path) {
    std::filesystem::path p(path);
    return p.make_preferred().string();
}

bool exists(const std::string& path) {
    return std::filesystem::exists(path);
}

bool isFile(const std::string& path) {
    return std::filesystem::is_regular_file(path);
}

bool isDirectory(const std::string& path) {
    return std::filesystem::is_directory(path);
}

bool isAbsolute(const std::string& path) {
    std::filesystem::path p(path);
    return p.is_absolute();
}

bool createDirectory(const std::string& path) {
    try {
        return std::filesystem::create_directories(path);
    } catch (const std::exception& e) {
        AV_LOGGER_ERRORF("Failed to create directory '{}': {}", path, e.what());
        return false;
    }
}

bool removeFile(const std::string& path) {
    try {
        return std::filesystem::remove(path);
    } catch (const std::exception& e) {
        AV_LOGGER_ERRORF("Failed to remove file '{}': {}", path, e.what());
        return false;
    }
}

} // namespace path_utils

// 时间工具实现
namespace time_utils {

int64_t getCurrentTimeMs() {
    return std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::steady_clock::now().time_since_epoch()).count();
}

int64_t getCurrentTimeUs() {
    return std::chrono::duration_cast<std::chrono::microseconds>(
        std::chrono::steady_clock::now().time_since_epoch()).count();
}

std::string formatTime(int64_t timeMs, const std::string& format) {
    auto time_t = std::chrono::system_clock::to_time_t(
        std::chrono::system_clock::time_point(
            std::chrono::milliseconds(timeMs)));
    
    std::ostringstream oss;
    oss << std::put_time(std::localtime(&time_t), format.c_str());
    return oss.str();
}

std::string formatDuration(int64_t durationMs) {
    int64_t hours = durationMs / (1000 * 60 * 60);
    int64_t minutes = (durationMs % (1000 * 60 * 60)) / (1000 * 60);
    int64_t seconds = (durationMs % (1000 * 60)) / 1000;
    int64_t ms = durationMs % 1000;
    
    std::ostringstream oss;
    if (hours > 0) {
        oss << hours << ":" << std::setfill('0') << std::setw(2) << minutes 
            << ":" << std::setw(2) << seconds;
    } else {
        oss << minutes << ":" << std::setfill('0') << std::setw(2) << seconds;
    }
    
    if (ms > 0) {
        oss << "." << std::setw(3) << ms;
    }
    
    return oss.str();
}

// Timer实现
Timer::Timer() {
    reset();
}

void Timer::start() {
    m_startTime = std::chrono::high_resolution_clock::now();
    m_running = true;
}

void Timer::stop() {
    if (m_running) {
        m_endTime = std::chrono::high_resolution_clock::now();
        m_running = false;
    }
}

void Timer::reset() {
    m_startTime = std::chrono::high_resolution_clock::now();
    m_endTime = m_startTime;
    m_running = false;
}

int64_t Timer::elapsedMs() const {
    auto endTime = m_running ? std::chrono::high_resolution_clock::now() : m_endTime;
    return std::chrono::duration_cast<std::chrono::milliseconds>(endTime - m_startTime).count();
}

int64_t Timer::elapsedUs() const {
    auto endTime = m_running ? std::chrono::high_resolution_clock::now() : m_endTime;
    return std::chrono::duration_cast<std::chrono::microseconds>(endTime - m_startTime).count();
}

bool Timer::isRunning() const {
    return m_running;
}

// ScopedTimer实现
ScopedTimer::ScopedTimer(const std::string& name) : m_name(name) {
    m_timer.start();
}

ScopedTimer::~ScopedTimer() {
    m_timer.stop();
    AV_LOGGER_INFOF("[Timer] {} took {} ms", m_name, m_timer.elapsedMs());
}

} // namespace time_utils

// 内存工具实现
namespace memory_utils {

size_t alignSize(size_t size, size_t alignment) {
    return (size + alignment - 1) & ~(alignment - 1);
}

void* alignedAlloc(size_t size, size_t alignment) {
#ifdef _WIN32
    return _aligned_malloc(size, alignment);
#else
    void* ptr = nullptr;
    if (posix_memalign(&ptr, alignment, size) != 0) {
        return nullptr;
    }
    return ptr;
#endif
}

void alignedFree(void* ptr) {
#ifdef _WIN32
    _aligned_free(ptr);
#else
    free(ptr);
#endif
}

// MemoryPool实现
MemoryPool::MemoryPool(size_t blockSize, size_t blockCount) 
    : m_blockSize(blockSize) {
    size_t totalSize = blockSize * blockCount;
    m_memory.resize(totalSize);
    
    // 初始化空闲块列表
    for (size_t i = 0; i < blockCount; ++i) {
        m_freeBlocks.push_back(m_memory.data() + i * blockSize);
    }
}

MemoryPool::~MemoryPool() {
    // 析构函数自动清理
}

void* MemoryPool::allocate() {
    std::lock_guard<std::mutex> lock(m_mutex);
    
    if (m_freeBlocks.empty()) {
        return nullptr;
    }
    
    void* ptr = m_freeBlocks.back();
    m_freeBlocks.pop_back();
    return ptr;
}

void MemoryPool::deallocate(void* ptr) {
    if (!ptr) return;
    
    std::lock_guard<std::mutex> lock(m_mutex);
    
    // 验证指针是否属于这个内存池
    uint8_t* bytePtr = static_cast<uint8_t*>(ptr);
    if (bytePtr >= m_memory.data() && 
        bytePtr < m_memory.data() + m_memory.size()) {
        m_freeBlocks.push_back(ptr);
    }
}

size_t MemoryPool::getAvailableBlocks() const {
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_freeBlocks.size();
}

} // namespace memory_utils

// FFmpeg工具实现
namespace ffmpeg_utils {

std::string errorToString(int errorCode) {
    char buffer[AV_ERROR_MAX_STRING_SIZE];
    av_strerror(errorCode, buffer, sizeof(buffer));
    return std::string(buffer);
}

bool checkError(int ret, const std::string& operation) {
    if (ret < 0) {
        AV_LOGGER_ERRORF("{} failed: {}", operation, errorToString(ret));
        return false;
    }
    return true;
}

std::string pixelFormatToString(AVPixelFormat format) {
    const char* name = av_get_pix_fmt_name(format);
    return name ? std::string(name) : "unknown";
}

std::string sampleFormatToString(AVSampleFormat format) {
    const char* name = av_get_sample_fmt_name(format);
    return name ? std::string(name) : "unknown";
}

std::string codecTypeToString(AVMediaType type) {
    const char* name = av_get_media_type_string(type);
    return name ? std::string(name) : "unknown";
}

bool isValidPixelFormat(AVPixelFormat format) {
    return format != AV_PIX_FMT_NONE && av_get_pix_fmt_name(format) != nullptr;
}

bool isValidSampleFormat(AVSampleFormat format) {
    return format != AV_SAMPLE_FMT_NONE && av_get_sample_fmt_name(format) != nullptr;
}

bool isValidSampleRate(int sampleRate) {
    return sampleRate > 0 && sampleRate <= 192000;
}

bool isValidChannels(int channels) {
    return channels > 0 && channels <= 32;
}

// 统一使用智能指针的帧分配函数
AVFramePtr allocateFrame(AVPixelFormat format, int width, int height) {
    AVFramePtr frame = makeAVFrame();
    if (!frame) {
        return nullptr;
    }
    
    frame->format = format;
    frame->width = width;
    frame->height = height;
    
    if (av_frame_get_buffer(frame.get(), 32) < 0) {
        return nullptr; // 智能指针自动释放
    }
    
    return frame;
}

AVFramePtr allocateAudioFrame(AVSampleFormat format, int sampleRate, int channels, int nbSamples) {
    AVFramePtr frame = makeAVFrame();
    if (!frame) {
        return nullptr;
    }
    
    frame->format = format;
    frame->sample_rate = sampleRate;
    frame->ch_layout.nb_channels = channels;
    frame->nb_samples = nbSamples;
    
    if (av_frame_get_buffer(frame.get(), 0) < 0) {
        return nullptr; // 智能指针自动释放
    }
    
    return frame;
}

void freeFrame(AVFrame** frame) {
    if (frame && *frame) {
        av_frame_free(frame);
    }
}

AVPacket* allocatePacket() {
    return av_packet_alloc();
}

void freePacket(AVPacket** packet) {
    if (packet && *packet) {
        av_packet_free(packet);
    }
}

bool initializeFFmpeg() {
    static bool initialized = false;
    if (initialized) {
        return true;
    }
    
    try {
        // FFmpeg 4.0+ 不需要显式注册
        av_log_set_level(AV_LOG_QUIET);
        initialized = true;
        AV_LOGGER_INFO("FFmpeg initialized successfully");
        return true;
    } catch (const std::exception& e) {
        AV_LOGGER_ERRORF("Failed to initialize FFmpeg: {}", e.what());
        return false;
    }
}

void cleanupFFmpeg() {
    // FFmpeg 4.0+ 不需要显式清理
    AV_LOGGER_INFO("FFmpeg cleanup completed");
}

} // namespace ffmpeg_utils
} // namespace av
