# Copyright (C) all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
#
# Main web interface for mailing list archives
#
# We focus on the lowest common denominators here:
# - targeted at text-only console browsers (w3m, links, etc..)
# - Only basic HTML, CSS only for line-wrapping <pre> text content for GUIs
#   and diff/syntax-highlighting (optional)
# - No JavaScript, graphics or icons allowed.
# - Must not rely on static content
# - UTF-8 is only for user-content, 7-bit US-ASCII for us
package PublicInbox::WWW;
use strict;
use v5.10.1;
use autodie qw(chdir opendir);
use PublicInbox::Config;
use PublicInbox::Git;
use PublicInbox::Hval;
use URI::Escape qw(uri_unescape);
use PublicInbox::MID qw(mid_escape);
use PublicInbox::GitHTTPBackend;
use PublicInbox::UserContent;
use PublicInbox::WwwStatic qw(r path_info_raw);
use PublicInbox::Eml;

# TODO: consider a routing tree now that we have more endpoints:
our $INBOX_RE = qr!\A/([\w\-][\w\.\-\+]*)!;
our $MID_RE = qr!([^/]+)!;
our $END_RE = qr!(T/|t/|d/|t\.mbox(?:\.gz)?|t\.atom|raw|)!;
our $ATTACH_RE = qr!([0-9][0-9\.]*)-($PublicInbox::Hval::FN)!;
our $OID_RE = qr![a-f0-9]{7,}!;

sub new {
	my ($class, $pi_cfg) = @_;
	bless { pi_cfg => $pi_cfg // PublicInbox::Config->new }, $class;
}

# backwards compatibility, do not use
sub run {
	my ($req, $method) = @_;
	PublicInbox::WWW->new->call($req->env);
}

sub call {
	my ($self, $env) = @_;
	my $ctx = { env => $env, www => $self };

	# we don't care about multi-value
	# '0' isn't a QUERY_STRING we care about
	if (my $qs = $env->{QUERY_STRING}) {
		utf8::decode($qs);
		$qs =~ tr/+/ /;
		%{$ctx->{qp}} = map {
			# we only use single-char query param keys
			if (s/\A([A-Za-z])=//) {
				$1 => uri_unescape($_)
			} elsif (/\A[a-z]\z/) { # some boolean options
				$_ => ''
			} else {
				() # ignored
			}
		} split(/[&;]+/, $qs);
	}
	my $path_info = path_info_raw($env);
	my $method = $env->{REQUEST_METHOD};

	if ($method eq 'POST') {
		if ($path_info =~ m!$INBOX_RE/(?:(?:git/)?([0-9]+)(?:\.git)?/)?
					(git-upload-pack)\z!x) {
			my ($epoch, $path) = ($2, $3);
			return invalid_inbox($ctx, $1) ||
				serve_git($ctx, $epoch, $path);
		} elsif ($path_info =~ m!$INBOX_RE/(\w+)\.sql\.gz\z!o) {
			return get_altid_dump($ctx, $1, $2);
		} elsif ($path_info =~ m!$INBOX_RE/$MID_RE/$ATTACH_RE\z!o) {
			my ($idx, $fn) = ($3, $4);
			return invalid_inbox_mid($ctx, $1, $2) ||
				get_attach($ctx, $idx, $fn);
		} elsif ($path_info =~ m!$INBOX_RE/$MID_RE/\z!o) {
			return invalid_inbox_mid($ctx, $1, $2) || mbox_results($ctx);
		} elsif ($path_info =~ m!$INBOX_RE/\z!o) {
			return invalid_inbox($ctx, $1) || mbox_results($ctx);
		}
	}
	elsif ($method !~ /\A(?:GET|HEAD)\z/) {
		return r(405);
	}

	# top-level indices and feeds
	if ($path_info eq '/') {
		require PublicInbox::WwwListing;
		PublicInbox::WwwListing->response($ctx);
	} elsif ($path_info eq '/manifest.js.gz') {
		require PublicInbox::ManifestJsGz;
		PublicInbox::ManifestJsGz->response($ctx);
	} elsif ($path_info =~ m!$INBOX_RE\z!o) {
		invalid_inbox($ctx, $1) || r301($ctx, $1);
	} elsif ($path_info =~ m!$INBOX_RE(?:/|/index\.html)?\z!o) {
		invalid_inbox($ctx, $1) || get_index($ctx);
	} elsif ($path_info =~ m!$INBOX_RE/(?:atom\.xml|new\.atom)\z!o) {
		invalid_inbox($ctx, $1) || get_atom($ctx);
	} elsif ($path_info =~ m!$INBOX_RE/new\.html\z!o) {
		invalid_inbox($ctx, $1) || get_new($ctx);
	} elsif ($path_info =~
			m!$INBOX_RE/topics_(new|active)\.(atom|html)\z!o) {
		get_topics($ctx, $1, $2, $3);
	} elsif ($path_info =~ m!$INBOX_RE/description\z!o) {
		get_description($ctx, $1);
	} elsif ($path_info =~ m!$INBOX_RE/(?:(?:git/)?([0-9]+)(?:\.git)?/)?
				($PublicInbox::GitHTTPBackend::ANY)\z!ox) {
		my ($epoch, $path) = ($2, $3);
		invalid_inbox($ctx, $1) || serve_git($ctx, $epoch, $path);
	} elsif ($path_info =~ m!$INBOX_RE/([a-zA-Z0-9_\-]+).mbox\.gz\z!o) {
		serve_mbox_range($ctx, $1, $2);
	} elsif ($path_info =~ m!$INBOX_RE/$MID_RE/$END_RE\z!o) {
		msg_page($ctx, $1, $2, $3);

	} elsif ($path_info =~ m!$INBOX_RE/$MID_RE/$ATTACH_RE\z!o) {
		my ($idx, $fn) = ($3, $4);
		invalid_inbox_mid($ctx, $1, $2) || get_attach($ctx, $idx, $fn);
	# in case people leave off the trailing slash:
	} elsif ($path_info =~ m!$INBOX_RE/$MID_RE/(T|t)\z!o) {
		my ($inbox, $mid_ue, $suffix) = ($1, $2, $3);
		$suffix .= $suffix =~ /\A[tT]\z/ ? '/#u' : '/';
		r301($ctx, $inbox, $mid_ue, $suffix);

	} elsif ($path_info =~ m!$INBOX_RE/$MID_RE/R/?\z!o) {
		my ($inbox, $mid_ue) = ($1, $2);
		r301($ctx, $inbox, $mid_ue, '#R');

	} elsif ($path_info =~ m!$INBOX_RE/$MID_RE/f/?\z!o) {
		r301($ctx, $1, $2);
	} elsif ($path_info =~ m!$INBOX_RE/_/text(?:/(.*))?\z!o) {
		get_text($ctx, $1, $2);
	} elsif ($path_info =~ m!$INBOX_RE/([a-zA-Z0-9_\-\.]+)\.css\z!o) {
		get_css($ctx, $1, $2);
	} elsif ($path_info =~ m!$INBOX_RE/manifest\.js\.gz\z!o) {
		get_inbox_manifest($ctx, $1, $2);
	} elsif ($path_info =~ m!$INBOX_RE/($OID_RE)/s/\z!o) {
		get_vcs_object($ctx, $1, $2);
	} elsif ($path_info =~ m!$INBOX_RE/($OID_RE)/s/
				($PublicInbox::Hval::FN)\z!ox) {
		get_vcs_object($ctx, $1, $2, $3);
	} elsif ($path_info =~ m!$INBOX_RE/($OID_RE)/s\z!o) {
		r301($ctx, $1, $2, 's/');
	} elsif ($path_info =~ m!$INBOX_RE/(\w+)\.sql\.gz\z!o) {
		get_altid_dump($ctx, $1, $2);
	# convenience redirects order matters
	} elsif ($path_info =~ m!$INBOX_RE/([^/]{2,})\z!o) {
		r301($ctx, $1, $2);
	} elsif ($path_info =~ m!\A/\+/([a-zA-Z0-9_\-\.]+)\.css\z!) {
		get_css($ctx, undef, $1); # for WwwListing
	} else {
		legacy_redirects($ctx, $path_info);
	}
}

# for CoW-friendliness, MOOOOO!  Even for single-process setups,
# we want to get all immortal allocations done early to avoid heap
# fragmentation since common allocators favor a large contiguous heap.
sub preload {
	my ($self) = @_;

	# populate caches used by Encode internally, since emails
	# may show up with any encoding.
	require Encode;
	Encode::find_encoding($_) for Encode->encodings(':all');

	require PublicInbox::ExtMsg;
	require PublicInbox::Feed;
	require PublicInbox::View;
	require PublicInbox::SearchThread;
	require PublicInbox::Eml;
	require PublicInbox::Mbox;
	require PublicInbox::ViewVCS;
	require PublicInbox::WwwText;
	require PublicInbox::WwwAttach;
	eval {
		require PublicInbox::Search;
		PublicInbox::Search::load_xapian();
	};
	for (qw(SearchView MboxGz WwwAltId)) {
		eval "require PublicInbox::$_;";
	}
	if (ref($self)) {
		my $pi_cfg = $self->{pi_cfg};
		if (defined($pi_cfg->{'publicinbox.cgitrc'})) {
			$pi_cfg->limiter('-cgit');
		}
		if ($pi_cfg->ALL) {
			require PublicInbox::Isearch;
			$pi_cfg->fill_all;
		}
		$self->cgit;
		$self->coderepo;
		$self->stylesheets_prepare($_) for ('', '../', '../../');
		$self->news_www;
	}
}

# private functions below

sub r404 {
	my ($ctx) = @_;
	if ($ctx && $ctx->{mid}) {
		require PublicInbox::ExtMsg;
		return PublicInbox::ExtMsg::ext_msg($ctx);
	}
	r(404);
}

sub news_cgit_fallback ($) {
	my ($ctx) = @_;
	my $res = $ctx->{www}->news_www->call($ctx->{env});

	$res->[0] == 404 and ($ctx->{www}->{cgit_fallback} //= do {
		my $c = $ctx->{www}->{pi_cfg}->{'publicinbox.cgit'} // 'first';
		$c ne 'first' # `fallback' and `rewrite' => true
	} // 0) and $res = $ctx->{www}->coderepo->srv($ctx);

	ref($res) eq 'ARRAY' && $res->[0] == 404 and
		$res = $ctx->{www}->cgit->call($ctx->{env}, $ctx);

	ref($res) eq 'ARRAY' && $res->[0] == 404 &&
			!$ctx->{www}->{cgit_fallback} and
		$res = $ctx->{www}->coderepo->srv($ctx);
	$res;
}

# returns undef if valid, array ref response if invalid
sub invalid_inbox ($$) {
	my ($ctx, $inbox) = @_;
	my $ibx = $ctx->{www}->{pi_cfg}->lookup_name($inbox) //
			$ctx->{www}->{pi_cfg}->lookup_ei($inbox);
	if (defined $ibx) {
		$ctx->{ibx} = $ibx;
		return;
	}

	# sometimes linkifiers (not ours!) screw up automatic link
	# generation and link things intended for nntp:// to https?://,
	# so try to infer links and redirect them to the appropriate
	# list URL.
	news_cgit_fallback($ctx);
}

# returns undef if valid, array ref response if invalid
sub invalid_inbox_mid {
	my ($ctx, $inbox, $mid_ue) = @_;
	my $ret = invalid_inbox($ctx, $inbox);
	return $ret if $ret;

	my $mid = $ctx->{mid} = uri_unescape($mid_ue);
	my $ibx = $ctx->{ibx};
	if ($mid =~ m!\A([a-f0-9]{2})([a-f0-9]{38})\z!) {
		my ($x2, $x38) = ($1, $2);
		# this is horrifically wasteful for legacy URLs:
		my $str = $ctx->{ibx}->msg_by_path("$x2/$x38") or return;
		my $s = PublicInbox::Eml->new($str);
		$mid = PublicInbox::MID::mid_clean($s->header_raw('Message-ID'));
		return r301($ctx, $inbox, mid_escape($mid));
	}
	undef;
}

# /$INBOX/new.atom                     -> Atom feed, includes replies
sub get_atom {
	my ($ctx) = @_;
	require PublicInbox::Feed;
	PublicInbox::Feed::generate($ctx);
}

# /$INBOX/new.html			-> HTML only
sub get_new {
	my ($ctx) = @_;
	require PublicInbox::Feed;
	PublicInbox::Feed::new_html($ctx);
}

# /$INBOX/topics_(new|active).(html|atom)
sub get_topics {
	my ($ctx, $ibx_name, $category, $type) = @_;
	require PublicInbox::WwwTopics;
	PublicInbox::WwwTopics::response($ctx, $ibx_name, $category, $type);
}

# /$INBOX/?r=$GIT_COMMIT                 -> HTML only
sub get_index {
	my ($ctx) = @_;
	require PublicInbox::Feed;
	if ($ctx->{env}->{QUERY_STRING} =~ /(?:\A|[&;])q=/) {
		require PublicInbox::SearchView;
		PublicInbox::SearchView::sres_top_html($ctx);
	} else {
		PublicInbox::Feed::generate_html_index($ctx);
	}
}

# /$INBOX/$MESSAGE_ID/raw                    -> raw mbox
sub get_mid_txt {
	my ($ctx) = @_;
	require PublicInbox::Mbox;
	PublicInbox::Mbox::emit_raw($ctx) || r(404);
}

# /$INBOX/$MESSAGE_ID/                   -> HTML content (short quotes)
sub get_mid_html {
	my ($ctx) = @_;
	require PublicInbox::View;
	PublicInbox::View::msg_page($ctx) || r404($ctx);
}

# /$INBOX/$MESSAGE_ID/t/
sub get_thread {
	my ($ctx, $flat) = @_;
	$ctx->{ibx}->over or return need($ctx, 'Overview');
	$ctx->{flat} = $flat;
	require PublicInbox::View;
	PublicInbox::View::thread_html($ctx);
}

# /$INBOX/_/text/$KEY/
# /$INBOX/_/text/$KEY/raw
# KEY may contain slashes
sub get_text {
	my ($ctx, $inbox, $key) = @_;
	my $r404 = invalid_inbox($ctx, $inbox);
	return $r404 if $r404;

	require PublicInbox::WwwText;
	PublicInbox::WwwText::get_text($ctx, $key);
}

# show git objects (blobs and commits)
# /$INBOX/$GIT_OBJECT_ID/s/
# /$INBOX/$GIT_OBJECT_ID/s/$FILENAME
sub get_vcs_object ($$$;$) {
	my ($ctx, $inbox, $oid, $filename) = @_;
	my $r404 = invalid_inbox($ctx, $inbox);
	return $r404 if $r404;
	return r(404) if !$ctx->{www}->{pi_cfg}->repo_objs($ctx->{ibx});
	require PublicInbox::ViewVCS;
	PublicInbox::ViewVCS::show($ctx, $oid, $filename);
}

sub get_altid_dump {
	my ($ctx, $inbox, $altid_pfx) =@_;
	my $r404 = invalid_inbox($ctx, $inbox);
	return $r404 if $r404;
	eval { require PublicInbox::WwwAltId } or return need($ctx, 'sqlite3');
	PublicInbox::WwwAltId::sqldump($ctx, $altid_pfx);
}

sub need {
	my ($ctx, $extra, $upref) = @_;
	require PublicInbox::WwwStream;
	$upref //= '../';
	PublicInbox::WwwStream::html_oneshot($ctx, 501, <<EOF);
<pre>$extra is not available for this public-inbox
<a\nhref="$upref">Return to index</a></pre>
EOF
}

# /$INBOX/$MESSAGE_ID/t.mbox           -> thread as mbox
# /$INBOX/$MESSAGE_ID/t.mbox.gz        -> thread as gzipped mbox
# note: I'm not a big fan of other compression formats since they're
# significantly more expensive on CPU than gzip and less-widely available,
# especially on older systems.  Stick to zlib since that's what git uses.
sub get_thread_mbox {
	my ($ctx, $sfx) = @_;
	my $over = $ctx->{ibx}->over or return need($ctx, 'Overview');
	require PublicInbox::Mbox;
	PublicInbox::Mbox::thread_mbox($ctx, $over, $sfx);
}


# /$INBOX/$MESSAGE_ID/t.atom		  -> thread as Atom feed
sub get_thread_atom {
	my ($ctx) = @_;
	$ctx->{ibx}->over or return need($ctx, 'Overview');
	require PublicInbox::Feed;
	PublicInbox::Feed::generate_thread_atom($ctx);
}

sub legacy_redirects {
	my ($ctx, $path_info) = @_;

	# single-message pages
	if ($path_info =~ m!$INBOX_RE/m/(\S+)/\z!o) {
		r301($ctx, $1, $2);
	} elsif ($path_info =~ m!$INBOX_RE/m/(\S+)/raw\z!o) {
		r301($ctx, $1, $2, 'raw');

	} elsif ($path_info =~ m!$INBOX_RE/f/(\S+)/\z!o) {
		r301($ctx, $1, $2);

	# thread display
	} elsif ($path_info =~ m!$INBOX_RE/t/(\S+)/\z!o) {
		r301($ctx, $1, $2, 't/#u');

	} elsif ($path_info =~ m!$INBOX_RE/t/(\S+)/mbox(\.gz)?\z!o) {
		r301($ctx, $1, $2, "t.mbox$3");

	# even older legacy redirects
	} elsif ($path_info =~ m!$INBOX_RE/m/(\S+)\.html\z!o) {
		r301($ctx, $1, $2);

	} elsif ($path_info =~ m!$INBOX_RE/t/(\S+)\.html\z!o) {
		r301($ctx, $1, $2, 't/#u');

	} elsif ($path_info =~ m!$INBOX_RE/f/(\S+)\.html\z!o) {
		r301($ctx, $1, $2);

	} elsif ($path_info =~ m!$INBOX_RE/(?:m|f)/(\S+)\.txt\z!o) {
		r301($ctx, $1, $2, 'raw');

	} elsif ($path_info =~ m!$INBOX_RE/t/(\S+)(\.mbox(?:\.gz)?)\z!o) {
		r301($ctx, $1, $2, "t$3");

	# legacy convenience redirects, order still matters
	} elsif ($path_info =~ m!$INBOX_RE/m/(\S+)\z!o) {
		r301($ctx, $1, $2);
	} elsif ($path_info =~ m!$INBOX_RE/t/(\S+)\z!o) {
		r301($ctx, $1, $2, 't/#u');
	} elsif ($path_info =~ m!$INBOX_RE/f/(\S+)\z!o) {
		r301($ctx, $1, $2);

	# some Message-IDs have slashes in them and the HTTP server
	# may try to be clever and unescape them :<
	} elsif ($path_info =~ m!$INBOX_RE/(\S+/\S+)/$END_RE\z!o) {
		msg_page($ctx, $1, $2, $3);

	# in case people leave off the trailing slash:
	} elsif ($path_info =~ m!$INBOX_RE/(\S+/\S+)/(T|t)\z!o) {
		r301($ctx, $1, $2, $3 eq 't' ? 't/#u' : $3);
	} elsif ($path_info =~ m!$INBOX_RE/(\S+/\S+)/f\z!o) {
		r301($ctx, $1, $2);
	} else {
		news_cgit_fallback($ctx);
	}
}

sub r301 {
	my ($ctx, $inbox, $mid_ue, $suffix) = @_;
	my $ibx = $ctx->{ibx};
	unless ($ibx) {
		my $r404 = invalid_inbox($ctx, $inbox);
		return $r404 if $r404;
		$ibx = $ctx->{ibx};
	}
	my $url = $ibx->base_url($ctx->{env});
	my $qs = $ctx->{env}->{QUERY_STRING};
	if (defined $mid_ue) {
		# common, and much nicer as '@' than '%40':
		$mid_ue =~ s/%40/@/g;
		$url .= $mid_ue . '/';
	}
	$url .= $suffix if (defined $suffix);
	$url .= "?$qs" if $qs ne '';

	[ 301,
	  [ Location => $url, 'Content-Type' => 'text/plain' ],
	  [ "Redirecting to $url\n" ] ]
}

sub msg_page {
	my ($ctx, $inbox, $mid_ue, $e) = @_;
	my $ret;
	$ret = invalid_inbox_mid($ctx, $inbox, $mid_ue) and return $ret;
	'' eq $e and return get_mid_html($ctx);
	'T/' eq $e and return get_thread($ctx, 1);
	't/' eq $e and return get_thread($ctx);
	't.atom' eq $e and return get_thread_atom($ctx);
	't.mbox' eq $e and return get_thread_mbox($ctx);
	't.mbox.gz' eq $e and return get_thread_mbox($ctx, '.gz');
	'raw' eq $e and return get_mid_txt($ctx);

	# legacy, but no redirect for compatibility:
	'f/' eq $e and return get_mid_html($ctx);
	if ($e eq 'd/') {
		require PublicInbox::View;
		return PublicInbox::View::diff_msg($ctx);
	}
	r404($ctx);
}

sub serve_git {
	my ($ctx, $epoch, $path) = @_;
	my $env = $ctx->{env};
	my $ibx = $ctx->{ibx};
	my $git = defined $epoch ? $ibx->git_epoch($epoch) : $ibx->git;
	$git ? PublicInbox::GitHTTPBackend::serve($env, $git, $path) : r404();
}

sub mbox_results {
	my ($ctx) = @_;
	if ($ctx->{env}->{QUERY_STRING} =~ /(?:\A|[&;])q=/) {
		$ctx->{ibx}->isrch or return need($ctx, 'search');
		require PublicInbox::SearchView;
		return PublicInbox::SearchView::mbox_results($ctx);
	}
	r404();
}

sub serve_mbox_range {
	my ($ctx, $inbox, $range) = @_;
	invalid_inbox($ctx, $inbox) || eval {
		require PublicInbox::Mbox;
		PublicInbox::Mbox::emit_range($ctx, $range);
	}
}

sub news_www {
	my ($self) = @_;
	$self->{news_www} //= do {
		require PublicInbox::NewsWWW;
		PublicInbox::NewsWWW->new($self->{pi_cfg});
	}
}

sub cgit {
	my ($self) = @_;
	$self->{cgit} //=
		(defined($self->{pi_cfg}->{'publicinbox.cgitrc'}) ? do {
			require PublicInbox::Cgit;
			PublicInbox::Cgit->new($self->{pi_cfg});
		} : undef) // do {
			require Plack::Util;
			Plack::Util::inline_object(call => sub { r404() });
		};
}

sub coderepo {
	my ($self) = @_;
	$self->{coderepo} //= do {
		require PublicInbox::WwwCoderepo;
		PublicInbox::WwwCoderepo->new($self->{pi_cfg});
	}
}

# GET $INBOX/manifest.js.gz
sub get_inbox_manifest ($$$) {
	my ($ctx, $inbox, $key) = @_;
	my $r404 = invalid_inbox($ctx, $inbox);
	return $r404 if $r404;
	require PublicInbox::ManifestJsGz;
	PublicInbox::ManifestJsGz::per_inbox($ctx);
}

sub get_attach {
	my ($ctx, $idx, $fn) = @_;
	require PublicInbox::WwwAttach;
	PublicInbox::WwwAttach::get_attach($ctx, $idx, $fn);
}

# User-generated content (UGC) may have excessively long lines
# and screw up rendering on some browsers, so we use pre-wrap.
#
# We also force everything to the same scaled font-size because GUI
# browsers (tested both Firefox and surf (webkit)) uses a larger font
# for the Search <form> element than the rest of the page.  Font size
# uniformity is important to people who rely on gigantic fonts.
# Finally, we use monospace to ensure the Search field and button
# has the same size and spacing as everything else which is
# <pre>-formatted anyways.
our $STYLE = 'pre{white-space:pre-wrap}*{font-size:100%;font-family:monospace}';

sub _read_css ($$$) {
	my ($fh, $mini, $fn) = @_;
	my $mtime = 0;
	my $local = PublicInbox::IO::read_all $fh; # sets _
	if ($local =~ /\S/) {
		$mtime = sprintf('%x',(stat(_))[9]);
		$local = $mini->($local);
	}
	# do not let BOFHs override userContent.css:
	return ($local, $mtime) if $local !~ /!\s*important\b/i;
	warn "W: ignoring $fn since it uses `!important'\n";
	();
}

sub stylesheets_prepare ($$) {
	my ($self, $upfx) = @_;
	my $mini = eval {
		require CSS::Minifier;
		sub { CSS::Minifier::minify(input => $_[0]) };
	} || eval {
		require CSS::Minifier::XS;
		sub { CSS::Minifier::XS::minify($_[0]) };
	} || sub { $_[0] };

	my $css_map = $self->{-css_map} //= {};
	my $stylesheets = $self->{pi_cfg}->{css} || [];
	my $links = [];
	my $inline_ok = 1;
	my (%css_dir, @css_dir, $import);

	foreach my $s (@$stylesheets) {
		my $attr = {};
		local $_ = $s;
		foreach my $k (qw(media title href load)) {
			if (s/\s*$k='([^']+)'// || s/\s*$k=(\S+)//) {
				$attr->{$k} = $1;
			}
		}
		# we may support `last' (to load CSS last at </html>)
		# or other load directives in the future...
		for my $l (split /,/, delete $attr->{load} // '') {
			if ($l eq 'import') {
				$inline_ok = 0;
				$import = $attr->{-do_import} = 1;
			} elsif ($l eq 'link') {
				$inline_ok = 0;
			} else {
				warn "W: load=$l not recognized (ignored)\n";
			}
		}
		if (defined $attr->{href}) {
			$inline_ok = 0;
		} else {
			my ($fn, $dir, $key);
			$fn = $_;
			($dir, $key) = (m!\A(?:(.+?)/)?([^/]+?)(?:\.css)?\z!i);
			if ($key !~ /\A[a-zA-Z0-9_\-\.]+\z/) {
				warn "ignoring $fn, non-ASCII word character\n";
				next;
			}
			my ($local, $mtime);
			if (my $rec = $css_map->{$key}) { # already loaded
				($local, $mtime) = @$rec;
			} elsif (open(my $fh, '<', $fn)) {
				($local, $mtime) = _read_css $fh, $mini, $fn;
				if ($local =~ /\@import\b/) {
					$import = $attr->{-do_import} = 1;
					push @css_dir, $dir if !$css_dir{$dir}++
				}
				$css_map->{$key} = [ $local, $mtime ];
			} else {
				warn "failed to open $fn: $!\n";
				next;
			}

			$attr->{href} = "$upfx$key.css?$mtime";
			if (defined($attr->{title})) { # browser-selectable
				$inline_ok = 0;
			} elsif (($attr->{media}||'screen') eq 'screen') {
				$attr->{-inline} = $local;
			}
		}
		push @$links, $attr;
	}
	my $buf = '<style>';
	if ($import) {
		my @links;
		for my $attr (@$links) {
			if (delete $attr->{-do_import}) {
				$buf .= '@import url("'.$attr->{href}.'") '.
					$attr->{media}.';';
			} else {
				push @links, $attr;
			}
		}
		$links = \@links;
	}
	# can't have $STYLE before @import(?)
	# <https://developer.mozilla.org/en-US/docs/Web/CSS/@import>
	$buf .= $STYLE;
	if ($inline_ok) {
		my @ext; # for media=print and whatnot
		foreach my $attr (@$links) {
			if (defined(my $str = delete $attr->{-inline})) {
				$buf .= $str;
			} else {
				push @ext, $attr;
			}
		}
		$links = \@ext;
	}
	$buf .= '</style>';

	if (@$links) {
		foreach my $attr (@$links) {
			delete $attr->{-inline};
			$buf .= "<link\ntype=text/css\nrel=stylesheet";
			while (my ($k, $v) = each %$attr) {
				$v = qq{"$v"} if $v =~ /[\s=]/;
				$buf .= qq{\n$k=$v};
			}
			$buf .= ' />';
		}
		$self->{"-style-$upfx"} = $buf;
	} else {
		$self->{-style_inline} = $buf;
	}
	# load potentially imported CSS files in known CSS directories
	if (@css_dir && !$self->{-css_dir}) {
		opendir my $cwddh, '.';
		for my $d (@css_dir) {
			CORE::opendir my $dh, $d or do {
				warn "W: opendir($d): $!";
				next;
			};
			chdir $dh;
			my @css = grep /\.css\z/i, readdir $dh;
			for my $fn (@css) {
				my ($key) = ($fn =~ m!([^/]+?)(?:\.css)?\z!i);
				next if $css_map->{$key};
				-f $fn or next;
				# no warning for autoloaded CSS
				open my $fh, '<', $fn or next;
				-T $fh or next;
				my ($local, $mtime) =
						_read_css $fh, $mini, "$d/$fn";
				$css_map->{$key} = [ $local, $mtime ];
			}
			chdir $cwddh;
		}
		$self->{-css_dir} = \@css_dir;
	}
	$css_map;
}

# returns an HTML fragment with <style> or <link> tags in them
# Called by WwwStream by nearly every HTML page
sub style {
	my ($self, $upfx) = @_;
	$self->{-style_inline} || $self->{"-style-$upfx"} || do {
		stylesheets_prepare($self, $upfx);
		$self->{-style_inline} || $self->{"-style-$upfx"}
	};
}

# /$INBOX/$KEY.css and /+/$KEY.css endpoints
# CSS is configured globally for all inboxes, but we access them on
# a per-inbox basis.  This allows administrators to setup per-inbox
# static routes to intercept the request before it hits PSGI
# inbox == undef => top-level WwwListing
sub get_css ($$$) {
	my ($ctx, $inbox, $key) = @_;
	my $r404 = defined($inbox) ? invalid_inbox($ctx, $inbox) : undef;
	return $r404 if $r404;
	my $self = $ctx->{www};
	my $css_map = $self->{-css_map} ||
		stylesheets_prepare($self, defined($inbox) ? '' : '+/');
	my $rec = $css_map->{$key};
	if (!defined($rec) && defined($inbox) && $key eq 'userContent') {
		$rec = [ PublicInbox::UserContent::sample($ctx) ];
	}
	srv_css_rec($rec);
}

sub srv_css_rec { # $_[0] may be ctx->{www}
	my $rec = $_[-1] // return r404();
	my ($css, undef) = @$rec; # TODO: Last-Modified + If-Modified-Since
	my $h = [ 'Content-Length', length($css), 'Content-Type', 'text/css' ];
	PublicInbox::GitHTTPBackend::cache_one_year($h);
	[ 200, $h, [ $css ] ];
}

sub get_description {
	my ($ctx, $inbox) = @_;
	invalid_inbox($ctx, $inbox) || do {
		my $d = $ctx->{ibx}->description . "\n";
		utf8::encode($d);
		[ 200, [ 'Content-Length', length($d),
			'Content-Type', 'text/plain' ], [ $d ] ];
	};
}

sub event_step { # called via requeue
	my ($self) = @_;
	# gzf = PublicInbox::GzipFilter == $ctx
	my $gzf = shift(@{$self->{-low_prio_q}}) // return;
	PublicInbox::DS::requeue($self) if scalar(@{$self->{-low_prio_q}});
	my $http = $gzf->{env}->{'psgix.io'}; # PublicInbox::HTTP
	$http->next_step($gzf->can('async_next'));
}

1;
