// Pasarle un comparador a std::sort, de tres maneras.
#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
#include <vector>

#include "lab/terms_io.h"

namespace {

bool by_text(const Term& a, const Term& b) {
    return a.text < b.text;
}

void print_terms(const char* label, const std::vector<Term>& terms) {
    std::cout << label << ":";
    for (const Term& term : terms) {
        std::cout << " " << term.text << "(" << term.weight << ")";
    }
    std::cout << "\n";
}

}  // namespace

int main() {
    std::vector<Term> terms = {{"lima", 40}, {"cusco", 90}, {"puno", 40}, {"tacna", 95}, {"arequipa", 90}};

    std::sort(terms.begin(), terms.end(), by_text);
    print_terms("por texto", terms);

    std::sort(terms.begin(), terms.end(), [](const Term& a, const Term& b) {
        if (a.weight != b.weight) {
            return a.weight > b.weight;
        }
        return a.text < b.text;
    });
    print_terms("por frecuencia, y texto en los empates", terms);

    std::vector<int> values = {3, 1, 2};
    std::sort(values.begin(), values.end(), std::greater<int>());
    std::cout << "de mayor a menor: " << values[0] << " " << values[1] << " " << values[2] << "\n";

    // En std::lower_bound, el comparador recibe un elemento y el valor buscado.
    std::sort(terms.begin(), terms.end(), by_text);
    std::string wanted = "lima";
    auto found = std::lower_bound(terms.begin(), terms.end(), wanted,
                                  [](const Term& term, const std::string& x) { return term.text < x; });
    std::cout << "lower_bound de lima: " << found->text << " en la posición " << (found - terms.begin()) << "\n";
    return 0;
}
