#!/usr/bin/perl
# $AFresh1: github_sync.pl,v 1.1 2020/06/13 22:42:13 afresh1 Exp $
use utf8;
use v5.16;
use warnings;
use warnings FATAL => 'utf8';
use open qw< :std :encoding(UTF-8) >;

my $github_account = shift;
die "Usage: $0 github_account\n" unless $github_account;
my $repos_url = "https://api.github.com/users/$github_account/repos";

# Copyright (c) 2020 Andrew Hewus Fresh <andrew@afresh1.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

my $response = HTTP::Tiny::JSON->new->get($repos_url);
die "GET $repos_url: $response->{status}: $response->{reason}\n"
    unless $response->{success};

foreach my $repo (@{ $response->{content} }) {
	my $clone_url = $repo->{clone_url};
	my $name = $clone_url =~ s{.*?\Q$github_account/}{}ir;

	local $@;
	eval {
		# I don't think I can actually --mirror if I want
		# to someday enable a two-way sync, but for now it works.
		git( clone => '--mirror', $clone_url )
		    unless -e $name;

		local $ENV{GIT_DIR} = $name;
		git(qw< remote update >);
		#git(qw< fetch --prune-tags --tags >);

		# TODO: Authentication and push of changes
		#git(qw< push  --all >);
	};

	warn if $@;
}

sub git {
	my (@args) = @_;
	system('git', @args) == 0 or die "git @args failed: $?";
}


package HTTP::Tiny::JSON;
use parent 'HTTP::Tiny';

BEGIN { our $VERSION = v0.0.1 }

use JSON::PP;

sub request {
	my ($self, @args) = @_;

	my $response = $self->SUPER::request(@args);

	return $response unless $response;

	if ( $response->{headers}->{'content-type'}
	    =~ /^application\/json\b/i )
	{
		$response->{raw_content} = $response->{content};
		$response->{content} = JSON::PP->new->utf8->decode(
		    $response->{content} );
	}

	return $response;
}

1;
