// Copyright (C) 2026 Kiyotsugu Arai
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// example_doc_rational_samples.cpp
// Verification harness for samples in api/Rational.html (ja+en).

#include <math/core/mp/Rational.hpp>
#include <math/core/mp/Rational/RationalConstants.hpp>
#include <iomanip>
#include <iostream>
#include <sstream>

using namespace sangi;

int main() {
    std::cout << std::setprecision(15);

    // ---- arithmetic ----------------------------------------------
    {
        std::cout << "[arithmetic]\n";
        Rational a(1, 3), b(1, 6);
        Rational c = a + b;
        Rational d = a * b;
        Rational e = a / b;
        Rational f = a - b;
        std::cout << "  a+b = " << c.toString() << "\n";
        std::cout << "  a*b = " << d.toString() << "\n";
        std::cout << "  a/b = " << e.toString() << "\n";
        std::cout << "  a-b = " << f.toString() << "\n";
    }

    // ---- continued fraction --------------------------------------
    {
        std::cout << "[continued fraction]\n";
        Rational r(355, 113);
        auto cf = r.toContinuedFraction();
        std::cout << "  355/113 cf = [";
        for (std::size_t i = 0; i < cf.size(); ++i) {
            if (i) std::cout << (i == 1 ? "; " : ", ");
            std::cout << cf[i].toString();
        }
        std::cout << "]\n";
        Rational r2 = Rational::fromContinuedFraction(cf);
        std::cout << "  round-trip = " << r2.toString() << "\n";
    }

    // ---- Bernoulli numbers ---------------------------------------
    {
        std::cout << "[bernoulli]\n";
        for (int n = 0; n <= 10; n += 2) {
            std::cout << "  B(" << n << ") = " << bernoulli(n).toString() << "\n";
        }
        std::cout << "  B(1) = " << bernoulli(1).toString() << "\n";
    }

    // ---- harmonic number -----------------------------------------
    {
        std::cout << "[harmonicNumber]\n";
        Rational h10 = harmonicNumber(10);
        std::cout << "  H(10) = " << h10.toString() << "\n";
        std::cout << "        ≈ " << h10.toDecimal(15) << "\n";
    }

    // ---- conversion / comparison ---------------------------------
    {
        std::cout << "[conversion]\n";
        Rational r(22, 7);
        std::cout << "  toDouble() = " << r.toDouble() << "\n";
        std::cout << "  toString() = " << r.toString() << "\n";
        std::cout << "  Rational(1,3) < Rational(1,2) = " << std::boolalpha
                  << (Rational(1, 3) < Rational(1, 2)) << "\n";
    }

    // ---- stream I/O -----------------------------------------------
    {
        std::cout << "[stream]\n";
        Rational r(22, 7);
        std::ostringstream oss;
        oss << r;
        std::cout << "  oss<<r = " << oss.str() << "\n";

        std::istringstream iss("3/4");
        Rational s;
        iss >> s;
        std::cout << "  parsed \"3/4\" = " << s.toString() << "\n";
    }

    // ---- NaN safety ----------------------------------------------
    {
        std::cout << "[NaN]\n";
        Rational nan = Rational(1, 0);
        std::cout << "  Rational(1,0).isNaN() = " << std::boolalpha << nan.isNaN() << "\n";
        std::cout << "  toString = " << nan.toString() << "\n";
    }

    return 0;
}
