#!/usr/bin/env php
<?php

require(__DIR__ . '/../vendor/autoload.php');

$ini = @parse_ini_file('discord.ini');

if (!$ini || !isset($ini['webhook'])) {
	return;
}

$commits = [];

for (;;) {

	$line = fgets(STDIN);

	if ($line === false) {
		break;
	}

	if (!sscanf($line, "%s %s refs/%s\n", $oRef, $nRef, $ref)) {
		continue;
	}

	if (basename(dirname($ref)) !== 'heads') {
		continue;
	}

	$ref = basename($ref);

	if (isset($ini['branch']) && $ini['branch'] !== $ref) {
		continue;
	}

	$log = `git log --format=fuller $oRef..$nRef`;

	if (!preg_match_all('~commit (?<sha>[a-f0-9]{40})\nAuthor:\s*(?<author>[^\n]+)\nAuthorDate:\s*(?<author_date>[^\n]+)\nCommit:\s*(?<committer>[^\n]+)\nCommitDate:\s*(?<commit_date>[^\n]+)(?<position>.*?)~s', $log, $matches, PREG_OFFSET_CAPTURE)) {
		continue;
	}

	foreach (array_keys($matches[0]) as $i) {

		$sha = $matches['sha'][$i][0];

		if (!preg_match('~^(?<name>.+) <(?<email>.+)>$~', $matches['committer'][$i][0], $m)) {
			continue;
		}

		$committerName = $m['name'];
		$committerEmail = strtolower($m['email']);

		if (!Nette\Utils\Validators::isEmail($committerEmail)) {
			$committerEmail = null;
		}

		$date = date_create_from_format('D M j H:i:s Y O', $matches['commit_date'][$i][0]);

		if (isset($matches[0][$i + 1])) {
			$message = substr($log, $matches['position'][$i][1], $matches[0][$i + 1][1] - $matches['position'][$i][1]);
		} else {
			$message = substr($log, $matches['position'][$i][1]);
		}

		$message = trim(preg_replace('~(^|\n)[ \t]+~', "\n", $message));
		$message = Nette\Utils\Strings::normalizeNewLines($message);

		if (($pos = strpos($message, "\n")) !== false) {
			$title = substr($message, 0, $pos);
			$message = trim(substr($message, $pos + 1));
		} else {
			$title = $message;
			$message = null;
		}

		$embed = new Adawolfa\DiscordHooks\Embed;
		$embed->title = $title;
		$embed->description = $message;

		if (isset($ini['url_commit'])) {
			$embed->url = strtr($ini['url_commit'], [
				'%sha%' => $sha,
				'%dir%' => basename(getcwd()),
			]);
		}

		$embed->author = new Adawolfa\DiscordHooks\Embed\Author($committerName);

		if (isset($ini['url_author'])) {
			$embed->author->url = strtr($ini['url_author'], [
				'%name%' => str_replace(' ', '+', $committerName),
				'%email%' => $committerEmail ?? '',
				'%dir%' => basename(getcwd()),
			]);
		}

		if ($committerEmail) {
			$embed->author->iconUrl = 'https://www.gravatar.com/avatar/' . md5($committerEmail) . '?s=80';
		}

		$embed->timestamp = $date;

		if (isset($ini['url_ref'])) {
			$branch = sprintf('[%s](%s)', $ref, strtr($ini['url_ref'], [
				'%ref%' => $ref,
				'%dir%' => basename(getcwd()),
			]));
		} else {
			$branch = $ref;
		}

		if ($embed->url !== null) {
			$revision = sprintf('[%s](%s)', substr($sha, 0, 7), $embed->url);
		} else {
			$revision = sprintf('`%s`', substr($sha, 0, 7));
		}

		$embed->fields[] = new Adawolfa\DiscordHooks\Embed\Field(
			'Branch',
			$branch,
			true
		);

		$embed->fields[] = new Adawolfa\DiscordHooks\Embed\Field(
			'Commit',
			$revision,
			true
		);

		$commits[] = $embed;

	}

}

$m = new Adawolfa\DiscordHooks\Message;

if (file_exists('description')) {
	$m->username = trim(file_get_contents('description'));
}

foreach (array_slice(array_reverse($commits), -10, 10) as $commit) {
	$m->embeds[] = $commit;
}

if (count($commits) > 10) {
    $m->content = sprintf('%d commits total.', count($commits));
}

$webHook = new Adawolfa\DiscordHooks\WebHook($ini['webhook']);
$webHook->execute($m);