#!/usr/bin/env raku
use CSS::Minifier;

my %*SUB-MAIN-OPTS = :named-anywhere, :numeric-suffix-as-value, :allow-no;

multi sub MAIN(Bool :$version!) { #= Print version and exit
    say CSS::Minifier.^ver
}

multi sub MAIN(
    Str :o(:$output),         #= Write to file instead of stdout
    Int :l(:$level) = 1,      #= Optimization level: 1 (safe normalizations) or 2 (structural optimizations)
    Bool :p(:$preserve-licenses), #= Keep /*! */ license comments (prepended to output)
    Bool :n(:$color-names),   #= Convert hex colors to named colors where possible
    Bool :m(:$color-masks) = True, #= Enable hex color shortening (use --no-color-masks or -/m to disable)
    Bool :u(:$preserve-unknown) = True,  #= Re-inject unknown CSS properties (use --no-preserve-unknown or -/u to disable)
    Bool :r(:$readable),      #= Separate rules with newlines (default: one line)
    Bool :v(:$verbose),       #= Show plugin names during processing
    *@files                   #= CSS files to read (reads from stdin if none given)
) {
    unless @files || !$*IN.t {
        note "No input: pass CSS files or pipe via stdin";
        note $*USAGE;
        exit 1;
    }
    my $css = @files
        ?? @files.map({ try { .IO.slurp } // do { note "Cannot read $_"; exit 1 } }).join("\n")
        !! $*IN.slurp;

    my $minified = try {
        CATCH { default { note "Failed to minify CSS: $_"; exit 1 } }
        CSS::Minifier.minify($css,
            :$level,
            :$verbose,
            :$preserve-licenses,
            :$color-masks,
            :$preserve-unknown,
            :$color-names,
            |(:sep("\n") if $readable),
        );
    };

    with $output { .IO.spurt($minified) }
    else         { $minified.print }
}

=begin pod

=head1 NAME

cssminify - CSS minifier CLI

=head1 SYNOPSIS

cssminify [--level=<n>] [--output=<file>] [--preserve-licenses] [--color-names] [--readable] [--verbose] [<file> ...]

Also accepts short flags: -o, -l, -p, -n, -m, -u, -r, -v.

=head1 DESCRIPTION

Reads CSS from files or stdin, minifies it, and writes to stdout or a file.

=head2 Options

=item C<-l|--level> - Optimization level: 1 (safe normalizations, default) or 2 (structural optimizations)
=item C<-o|--output> - Write to file instead of stdout
=item C<-p|--preserve-licenses> - Keep license comments (extracted before parse, prepended to output)
=item C<-n|--color-names> - Convert hex colors to named colors where possible
=item C<--color-masks> / C<--no-color-masks> (short: C<-m> / C<-/m>) - Enable/disable hex color shortening
=item C<--preserve-unknown> / C<--no-preserve-unknown> (short: C<-u> / C<-/u>) - Enable/disable unknown-property preservation (default: enabled)
=item C<-r|--readable> - Separate rules with newlines (default: one line)
=item C<-v|--verbose> - Log plugin names to stderr during processing
=item C<--version> - Print version and exit

=head2 Examples

    cssminify input.css > output.css
    cssminify -l2 input.css -o output.css
    cssminify -r -p input.css
    cssminify --no-preserve-unknown input.css
    cat input.css | cssminify --color-names

=head1 AUTHOR

Sasha Abbott <sashaa@disroot.org>

=head1 COPYRIGHT AND LICENSE

This library is free software; you can redistribute it and/or modify it under CC0.

=end pod
