# Copyright (C) all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>

# "lei blob $OID" command
# TODO: this doesn't scan submodules, but maybe it should
package PublicInbox::LeiBlob;
use strict;
use v5.10.1;
use parent qw(PublicInbox::IPC);
use autodie qw(open seek);
use PublicInbox::Spawn qw(run_wait run_qx which);
use PublicInbox::DS;
use PublicInbox::Eml;
use PublicInbox::Git qw(git_exe);
use PublicInbox::IO qw(read_all);

sub get_git_dir ($$) {
	my ($lei, $d) = @_;
	return $d if -d "$d/objects" && -d "$d/refs" && -e "$d/HEAD";

	my $cmd = [ git_exe, qw(rev-parse --git-dir) ];
	my $opt = { '-C' => $d };
	if (defined($lei->{opt}->{cwd})) { # --cwd used, report errors
		$opt->{2} = $lei->{2};
	} else { # implicit --cwd, quiet errors
		open $opt->{2}, '>', '/dev/null';
	}
	chomp(my $git_dir = run_qx($cmd, {GIT_DIR => undef}, $opt));
	$? ? undef : $git_dir;
}

sub solver_user_cb { # called by solver when done
	my ($res, $self) = @_;
	my $lei = $self->{lei};
	my $log_buf = delete $lei->{'log_buf'};
	$$log_buf =~ s/^/# /sgm;
	ref($res) eq 'ARRAY' or return $lei->child_error(0, $$log_buf);
	$lei->qerr($$log_buf);
	my ($git, $oid, $type, $size, $di) = @$res;

	# don't try to support all the git-show(1) options for non-blob,
	# this is just a convenience:
	$type ne 'blob' and warn <<EOM;
# $oid is a $type of $size bytes in:\n#\t$git->{git_dir}
EOM
	my $cmd = $git->cmd('show', $oid);
	my $rdr = { 1 => $lei->{1}, 2 => $lei->{2} };
	run_wait($cmd, $lei->{env}, $rdr) and $lei->child_error($?);
}

sub do_solve_blob { # via wq_do
	my ($self) = @_;
	my $lei = $self->{lei};
	my $git_dirs = $lei->{opt}->{'git-dir'};
	my $hints = {};
	for my $x (qw(oid-a path-a path-b)) {
		my $v = $lei->{opt}->{$x} // next;
		$x =~ tr/-/_/;
		$hints->{$x} = $v;
	}
	open my $log, '+>', \(my $log_buf = '');
	$lei->{log_buf} = \$log_buf;
	my $git = $lei->{ale}->git;
	my @rmt = map {
		PublicInbox::LeiRemote->new($lei, $_)
	} $self->{lxs}->remotes;
	my $solver = bless {
		gits => [ map {
				PublicInbox::Git->new($lei->rel2abs($_))
			} @$git_dirs ],
		user_cb => \&solver_user_cb,
		uarg => $self,
		# -cur_di, -msg => temporary fields for Qspawn callbacks
		inboxes => [ $self->{lxs}->locals, @rmt ],
	}, 'PublicInbox::SolverGit';
	local $PublicInbox::DS::in_loop = 0; # waitpid synchronously
	$solver->solve($lei->{env}, $log, $self->{oid_b}, $hints);
}

sub cat_attach_i { # Eml->each_part callback
	my ($part, $depth, $idx) = @{$_[0]};
	my $lei = $_[1];
	my $want = $lei->{-attach_idx} // return;
	return if $idx ne $want; # [0-9]+(?:\.[0-9]+)+
	delete $lei->{-attach_idx};
	$lei->out($part->body);
}

sub extract_attach ($$$) {
	my ($lei, $blob, $bref) = @_;
	my $eml = PublicInbox::Eml->new($bref);
	$eml->each_part(\&cat_attach_i, $lei, 1);
	my $idx = delete $lei->{-attach_idx};
	defined($idx) and return $lei->fail(<<EOM);
E: attachment $idx not found in $blob
EOM
}

sub lei_blob {
	my ($lei, $blob) = @_;
	$lei->start_pager if -t $lei->{1};
	my $opt = $lei->{opt};
	my $has_hints = grep(defined, @$opt{qw(oid-a path-a path-b)});
	my $lxs;
	if ($blob =~ s/:([0-9\.]+)\z//) {
		$lei->{-attach_idx} = $1;
		$opt->{mail} = 1;
	}

	# first, see if it's a blob returned by "lei q" JSON output:k
	if ($opt->{mail} // ($has_hints ? 0 : 1)) {
		if (grep(defined, @$opt{qw(include only)})) {
			$lxs = $lei->lxs_prepare;
			$lei->ale->refresh_externals($lxs, $lei);
		}
		my $rdr = {};
		if ($opt->{mail}) {
			open $rdr->{2}, '+>', undef;
		} else {
			open $rdr->{2}, '>', '/dev/null';
		}
		my $cmd = $lei->ale->git->cmd('cat-file', 'blob', $blob);
		my $cerr;
		if (defined $lei->{-attach_idx}) {
			my $buf = run_qx($cmd, $lei->{env}, $rdr);
			return extract_attach($lei, $blob, \$buf) unless $?;
			$cerr = $?;
		} else {
			$rdr->{1} = $lei->{1}; # write directly to client
			$cerr = run_wait($cmd, $lei->{env}, $rdr) or return;
		}
		# fall back to unimported ('lei index') and inflight blobs
		my $lms = $lei->lms;
		my $bref = ($lms ? $lms->local_blob($blob, 1) : undef) // do {
			my $sto = $lei->{sto} // $lei->_lei_store;
			$sto && $sto->{-wq_s1} ? $sto->wq_do('cat_blob', $blob)
						: undef;
		};
		$bref and return $lei->{-attach_idx} ?
					extract_attach($lei, $blob, $bref) :
					$lei->out($$bref);
		if ($opt->{mail}) {
			seek $rdr->{2}, 0, 0; # regular file (see above)
			return $lei->child_error($cerr, read_all($rdr->{2}));
		} # else: fall through to solver below
	}

	# maybe it's a non-email (code) blob from a coderepo
	my $git_dirs = $opt->{'git-dir'} //= [];
	if ($opt->{'cwd'} // 1) {
		my $cgd = get_git_dir($lei, '.');
		unshift(@$git_dirs, $cgd) if defined $cgd;
	}
	return $lei->fail('no --git-dir to try') unless @$git_dirs;
	unless ($lxs) {
		$lxs = $lei->lxs_prepare or return;
		$lei->ale->refresh_externals($lxs, $lei);
	}
	if ($lxs->remotes) {
		require PublicInbox::LeiRemote;
		$lei->{curl} //= which('curl') or return
			$lei->fail('curl needed for '.join(', ',$lxs->remotes));
		$lei->_lei_store(1)->write_prepare($lei);
	}
	require PublicInbox::SolverGit;
	my $self = bless { lxs => $lxs, oid_b => $blob }, __PACKAGE__;
	my ($op_c, $ops) = $lei->workers_start($self, 1);
	$lei->{wq1} = $self;
	$self->wq_io_do('do_solve_blob', []);
	$self->wq_close;
	$lei->wait_wq_events($op_c, $ops);
}

sub ipc_atfork_child {
	my ($self) = @_;
	$self->{lei}->_lei_atfork_child;
	$self->SUPER::ipc_atfork_child;
}

1;
