// SLS 批量上传功能测试用例

use pi_logger::ali_sls::{SLBatchConfig, SLSAppender};
use pi_logger::encode_sls::SLSEncoder;
use pi_logger::encode_json::JsonEncoder;
use pi_async_rt::rt::multi_thread::{MultiTaskRuntimeBuilder, StealableTaskPool};
use async_httpc::AsyncHttpcBuilder;
use log4rs::append::Append;

/// 创建测试用的运行时
fn create_test_runtime() -> pi_async_rt::rt::multi_thread::MultiTaskRuntime<()> {
    let len = 4;
    let pool = StealableTaskPool::with(len, 1000000, [1, 1], 3000);
    let builder = MultiTaskRuntimeBuilder::new(pool)
        .thread_prefix("TEST")
        .thread_stack_size(2 * 1024 * 1024)
        .init_worker_size(len)
        .set_worker_limit(len, len)
        .set_timeout(10)
        .set_timer_interval(1);
    builder.build()
}

/// 超时触发测试：使用 info! 发送日志
#[test]
fn test_batch_trigger_by_timeout() {
    let rt = create_test_runtime();
    let httpc = AsyncHttpcBuilder::new().build().unwrap();

    // 使用短超时快速测试
    let config = SLBatchConfig {
        batch_bytes: 1024 * 100,   // 100KB 触发
        timeout_secs: 5,            // 5 秒超时
        max_retries: 3,
        retry_delay_ms: 1000,
    };

    let url = "https://gcwl-logs.cn-chengdu.log.aliyuncs.com/logstores/logs_test/track".to_string();

    // 创建 SLS Appender
    let appender = SLSAppender::builder()
        .encoder(Box::new(SLSEncoder::new()))
        .source("test-project".to_string())
        .batch_config(config)
        .build(url, rt, httpc)
        .expect("Failed to create SLS appender");

    println!("Testing appender directly with 5 log messages...");

    // 直接在一个表达式中完成 record 创建和 append
    // 这样可以避免 format_args 的生命周期问题
    appender.append(
        &log::Record::builder()
            .level(log::Level::Info)
            .args(format_args!("test timeout message 1"))
            .build()
    ).expect("Direct appender call failed");
    println!("Sent message 1 via direct appender call");

    appender.append(
        &log::Record::builder()
            .level(log::Level::Info)
            .args(format_args!("test timeout message 2"))
            .build()
    ).expect("Direct appender call failed");
    println!("Sent message 2 via direct appender call");

    appender.append(
        &log::Record::builder()
            .level(log::Level::Info)
            .args(format_args!("test timeout message 3"))
            .build()
    ).expect("Direct appender call failed");
    println!("Sent message 3 via direct appender call");

    appender.append(
        &log::Record::builder()
            .level(log::Level::Info)
            .args(format_args!("test timeout message 4"))
            .build()
    ).expect("Direct appender call failed");
    println!("Sent message 4 via direct appender call");

    appender.append(
        &log::Record::builder()
            .level(log::Level::Info)
            .args(format_args!("test timeout message 5"))
            .build()
    ).expect("Direct appender call failed");
    println!("Sent message 5 via direct appender call");

    println!("All messages sent, waiting for batch processing and timeout...");

    // 等待超时触发（5秒）+ 发送时间
    std::thread::sleep(std::time::Duration::from_secs(7));

    println!("Timeout trigger test passed! Check SLS console for logs.");
}

/// JsonEncoder 与 SLSAppender 组合测试
#[test]
fn test_json_encoder_with_sls_appender() {
    let rt = create_test_runtime();
    let httpc = AsyncHttpcBuilder::new().build().unwrap();

    // 使用短超时快速测试
    let config = SLBatchConfig {
        batch_bytes: 1024 * 100,   // 100KB 触发
        timeout_secs: 5,            // 5 秒超时
        max_retries: 3,
        retry_delay_ms: 1000,
    };

    let url = "https://gcwl-logs.cn-chengdu.log.aliyuncs.com/logstores/logs_test/track".to_string();

    // 使用 JsonEncoder 创建 SLS Appender
    let appender = SLSAppender::builder()
        .encoder(Box::new(JsonEncoder::new(None)))
        .source("json-test".to_string())
        .batch_config(config)
        .build(url, rt, httpc)
        .expect("Failed to create SLS appender with JsonEncoder");

    println!("Testing JsonEncoder with SLSAppender...");

    // 发送多条测试日志，JsonEncoder 会将日志序列化为 JSON 格式
    appender.append(
        &log::Record::builder()
            .level(log::Level::Info)
            .args(format_args!("JsonEncoder test message 1"))
            .target("test::module")
            .module_path(Some("test::module"))
            .file(Some("test.rs"))
            .line(Some(10))
            .build()
    ).expect("Failed to append log 1");
    println!("Sent message 1 via JsonEncoder");

    appender.append(
        &log::Record::builder()
            .level(log::Level::Debug)
            .args(format_args!("JsonEncoder test message 2"))
            .target("test::module")
            .module_path(Some("test::module"))
            .file(Some("test.rs"))
            .line(Some(11))
            .build()
    ).expect("Failed to append log 2");
    println!("Sent message 2 via JsonEncoder");

    appender.append(
        &log::Record::builder()
            .level(log::Level::Warn)
            .args(format_args!("JsonEncoder test message 3"))
            .target("test::module")
            .module_path(Some("test::module"))
            .file(Some("test.rs"))
            .line(Some(12))
            .build()
    ).expect("Failed to append log 3");
    println!("Sent message 3 via JsonEncoder");

    appender.append(
        &log::Record::builder()
            .level(log::Level::Error)
            .args(format_args!("JsonEncoder test message 4"))
            .target("test::module")
            .module_path(Some("test::module"))
            .file(Some("test.rs"))
            .line(Some(13))
            .build()
    ).expect("Failed to append log 4");
    println!("Sent message 4 via JsonEncoder");

    appender.append(
        &log::Record::builder()
            .level(log::Level::Info)
            .args(format_args!("JsonEncoder test message 5"))
            .target("test::module")
            .module_path(Some("test::module"))
            .file(Some("test.rs"))
            .line(Some(14))
            .build()
    ).expect("Failed to append log 5");
    println!("Sent message 5 via JsonEncoder");

    println!("All JsonEncoder messages sent, waiting for batch processing...");

    // 等待超时触发（5秒）+ 发送时间
    std::thread::sleep(std::time::Duration::from_secs(7));

    println!("JsonEncoder with SLSAppender test passed! Check SLS console for JSON formatted logs.");
}

/// SLSEncoder 与 __logs__ 字段兼容性测试
#[test]
fn test_sls_encoder_with_logs_array() {
    let rt = create_test_runtime();
    let httpc = AsyncHttpcBuilder::new().build().unwrap();

    let config = SLBatchConfig {
        batch_bytes: 1024 * 100,
        timeout_secs: 5,
        max_retries: 3,
        retry_delay_ms: 1000,
    };

    let url = "https://gcwl-logs.cn-chengdu.log.aliyuncs.com/logstores/logs_test/track".to_string();

    // 使用 SLSEncoder 创建 SLS Appender
    let appender = SLSAppender::builder()
        .encoder(Box::new(SLSEncoder::new()))
        .source("sls-logs-array-test".to_string())
        .batch_config(config)
        .build(url, rt, httpc)
        .expect("Failed to create SLS appender with SLSEncoder");

    println!("Testing SLSEncoder with __logs__ array...");

    // 测试包含 __logs__ 数组的 JSON
    let logs_with_array = r#"{"__logs__":[{"bievent":"gisum","project":"yszz_local_test","time":"1768961943","uid":"100009186","g_k":"grow/创造次数","g_v":"627"},{"bievent":"levelup","project":"yszz_local_test","time":"1768961944","uid":"100009186","level":"5"}]}"#;

    appender.append(
        &log::Record::builder()
            .level(log::Level::Info)
            .args(format_args!("{}", logs_with_array))
            .build()
    ).expect("Failed to append logs with __logs__ array");

    println!("Sent __logs__ array with 2 entries");

    // 测试普通消息（保持原有逻辑）
    appender.append(
        &log::Record::builder()
            .level(log::Level::Info)
            .args(format_args!("Normal message without __logs__"))
            .build()
    ).expect("Failed to append normal message");

    println!("Sent normal message");

    std::thread::sleep(std::time::Duration::from_secs(7));

    println!("SLSEncoder with __logs__ array test passed! Check SLS console for logs.");
}

/// SLSEncoder 各种 JSON 格式兼容性测试
#[test]
fn test_sls_encoder_json_formats() {
    let rt = create_test_runtime();
    let httpc = AsyncHttpcBuilder::new().build().unwrap();

    let config = SLBatchConfig {
        batch_bytes: 1024 * 100,
        timeout_secs: 5,
        max_retries: 3,
        retry_delay_ms: 1000,
    };

    let url = "https://gcwl-logs.cn-chengdu.log.aliyuncs.com/logstores/logs_test/track".to_string();

    let appender = SLSAppender::builder()
        .encoder(Box::new(SLSEncoder::new()))
        .source("sls-json-formats-test".to_string())
        .batch_config(config)
        .build(url, rt, httpc)
        .expect("Failed to create SLS appender");

    println!("Testing SLSEncoder with various JSON formats...");

    // 测试1: 包含 __logs__ 数组的 JSON
    let logs_with_array = r#"{"__logs__":[{"event":"test1"},{"event":"test2"}]}"#;
    appender.append(
        &log::Record::builder()
            .level(log::Level::Info)
            .args(format_args!("{}", logs_with_array))
            .build()
    ).expect("Failed to append __logs__ array");
    println!("Test 1: __logs__ array - sent 2 entries");

    // 测试2: JSON 对象但不包含 __logs__（直接使用，不包装 message）
    let json_without_logs = r#"{"action":"click","page":"home","userId":"12345"}"#;
    appender.append(
        &log::Record::builder()
            .level(log::Level::Info)
            .args(format_args!("{}", json_without_logs))
            .build()
    ).expect("Failed to append JSON without __logs__");
    println!("Test 2: JSON without __logs__ - sent directly");

    // 测试3: 普通文本消息（包装到 message 字段）
    appender.append(
        &log::Record::builder()
            .level(log::Level::Info)
            .args(format_args!("This is a plain text message"))
            .build()
    ).expect("Failed to append plain text");
    println!("Test 3: Plain text - wrapped in message field");

    // 测试4: 更复杂的 JSON 对象
    let complex_json = r#"{"timestamp":"1768961943","level":"INFO","service":"api","data":{"count":42,"status":"active"}}"#;
    appender.append(
        &log::Record::builder()
            .level(log::Level::Info)
            .args(format_args!("{}", complex_json))
            .build()
    ).expect("Failed to append complex JSON");
    println!("Test 4: Complex JSON - sent directly");

    // 测试5: 空的 __logs__ 数组
    let empty_logs_array = r#"{"__logs__":[]}"#;
    appender.append(
        &log::Record::builder()
            .level(log::Level::Info)
            .args(format_args!("{}", empty_logs_array))
            .build()
    ).expect("Failed to append empty __logs__ array");
    println!("Test 5: Empty __logs__ array - sent");

    std::thread::sleep(std::time::Duration::from_secs(7));

    println!("SLSEncoder JSON formats test passed! Check SLS console for all formats.");
}
