// 20_exceptions.cpp
// 异常实战演练：try/catch/throw、标准异常层次、noexcept 的综合应用

#include <cstdio>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>

/// @brief 安全的整数除法，除数为零时抛出异常
int safe_divide(int dividend, int divisor) {
    if (divisor == 0) {
        throw std::invalid_argument("Division by zero is not allowed");
    }
    return dividend / divisor;
}

/// @brief 解析文件中的整数行
/// @throws std::runtime_error 文件无法打开
std::vector<int> parse_int_file(const std::string& path) {
    std::ifstream file(path);
    if (!file.is_open()) {
        throw std::runtime_error("Cannot open file: " + path);
    }

    std::vector<int> result;
    std::string line;
    int line_num = 0;

    while (std::getline(file, line)) {
        ++line_num;
        try {
            std::size_t pos = 0;
            int value = std::stoi(line, &pos);
            if (pos != line.size()) {
                throw std::invalid_argument("Trailing characters");
            }
            result.push_back(value);
        } catch (const std::exception& e) {
            std::cerr << "[parse_int_file] Error at line " << line_num << ": " << e.what() << "\n";
            throw; // 重新抛出，让调用者决定怎么处理
        }
    }
    return result;
}

/// @brief 格式化并打印解析结果（noexcept 示例）
void print_results(const std::vector<int>& values) noexcept {
    std::cout << "Parsed " << values.size() << " values: ";
    for (std::size_t i = 0; i < values.size(); ++i) {
        if (i > 0)
            std::cout << ", ";
        std::cout << values[i];
    }
    std::cout << "\n";
}

int main() {
    // 安全除法演示
    std::cout << "=== Safe Divide Demo ===\n";
    struct {
        int a, b;
        const char* label;
    } cases[] = {
        {10, 3, "normal"},
        {7, 0, "zero"},
        {-20, 4, "negative"},
    };
    for (const auto& tc : cases) {
        try {
            std::cout << "  " << tc.a << " / " << tc.b << " = " << safe_divide(tc.a, tc.b) << "\n";
        } catch (const std::invalid_argument& e) {
            std::cout << "  " << tc.label << ": " << e.what() << "\n";
        }
    }

    // 文件解析演示
    std::cout << "\n=== File Parser Demo ===\n";
    const char* test_path = "/tmp/exception_test_data.txt";
    {
        std::ofstream out(test_path);
        out << "42\n100\nnot_a_number\n7\n";
    }
    try {
        auto values = parse_int_file(test_path);
        print_results(values);
    } catch (const std::exception& e) {
        std::cout << "  Caught: " << e.what() << "\n";
    }

    // catch-all 演示
    std::cout << "\n=== Catch-all Demo ===\n";
    try {
        throw 42;
    } catch (const std::exception&) {
        std::cout << "  Standard\n";
    } catch (...) {
        std::cout << "  Unknown exception\n";
    }

    return 0;
}
