import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

public class DecoratorDemo {
    public static void main(String[] args) throws IOException {
        Path file = Path.of("build", "demo", "informe.txt");
        Files.createDirectories(file.getParent());

        // Tres capas: PrintWriter (println, printf) sobre CountingWriter (cuenta)
        // sobre el BufferedWriter que da Files (escribe en el archivo).
        CountingWriter counter = new CountingWriter(Files.newBufferedWriter(file));
        try (PrintWriter out = new PrintWriter(counter)) {
            out.println("Informe del día");
            out.printf("%-10s %5d%n", "Lima", 18);
            out.printf("%-10s %5d%n", "Cusco", 9);
        }
        IO.println("líneas escritas: " + counter.lines());

        // Error común: no cerrar. Lo escrito se queda en el buffer, no en el archivo.
        Path other = file.resolveSibling("sin-cerrar.txt");
        java.io.BufferedWriter leaky = Files.newBufferedWriter(other);
        leaky.write("esto todavía no está en el disco\n");
        IO.println("antes de close: " + Files.size(other) + " bytes");
        leaky.close();
        IO.println("después de close: " + Files.size(other) + " bytes");

        // Al leer, las capas van al revés: bytes -> caracteres -> líneas.
        try (InputStream bytes = Files.newInputStream(file);
                InputStreamReader chars = new InputStreamReader(bytes, StandardCharsets.UTF_8);
                BufferedReader lines = new BufferedReader(chars)) {
            String line;
            while ((line = lines.readLine()) != null) {
                IO.println("> " + line);
            }
        }
    }
}
