#!/usr/bin/php
<?php

echo "Preparing Moments components ...\n";

$gitignore = file_get_contents('.gitignore');
if ($gitignore[-1] != "\n") {
	$gitignore .= "\n";
}
$gitignoreChanged = false;

function addToGitIgnore($file)
{
	global $gitignore, $gitignoreChanged;
	if (strpos($gitignore, $file) === false) {
		$gitignore .= $file . "\n";
		$gitignoreChanged = true;
	}
}

function mergeArray($arr, $add)
{
	foreach ($add as $key => $value) {
		if (!isset($arr[$key])) {
			$arr[$key] = [];
		}
		if (is_array($value)) {
			$arr[$key] = array_merge($arr[$key], $value);
		} else {
			$arr[$key][] = $value;
		}
	}
	return $arr;
}

if (file_exists('config/files.json')) {
	$f = json_decode(file_get_contents('config/files.json'), true);
	foreach (($f ?? []) as $file => $desired) {
		if (empty($desired['name'])) {
			echo " [ERR] Invalid entry in config\n";
			print_r($desired);
		}
		if (!file_exists($desired['name'])) {
			echo " - Missing ${desired['name']}, creating it\n";
			switch ($desired['type']) {
				case 'dir':
				case 'directory':
				case 'folder':
					mkdir($desired['name'], 0777, true);
					break;
				case 'file':
					$content = '';
					if (!empty($desired['content'])) {
						$content = $desired['content'];
					}
					if (!empty($desired['copy'])) {
						copy($desired['copy'], $desired['name']);
					} else {
						file_put_contents($desired['name'], $content);
					}
					break;
			}
			continue;
		}
		if (!empty($desired['chmod'])) {
			if ($desired['chmod'][0] === '0') {
				// JSON cannot handle octal numbers, so it's a string we have to convert
				$desired['chmod'] = octdec(substr($desired['chmod'], 1));
			}
			chmod($desired['name'], $desired['chmod']);
		}
		if (!empty($desired['chown'])) {
			chown($desired['name'], $desired['chown']);
		}
	}
}

$bundleConf = [
	'routes' => [],
	'services' => [],
	'bundles' => [],
	'include-scripts' => [],
	'include-styles' => [],
	'events' => [],
];

$f = json_decode(file_get_contents('composer.json'), true);
foreach ($f['require'] as $project => $version) {
	$dir = getcwd() . '/vendor/' . $project . '/';
	$conf = $dir . 'moments-bundle.json';
	if (file_exists($conf)) {
		echo " - $project \n";
		$f = json_decode(file_get_contents($conf), true);
		
		foreach ($f['scripts'] ?? [] as $script) {
			include($dir . $script);
		}
		
		$bundleConf['bundles'][] = $project;
		$bundleConf['routes'] += $f['routes'] ?? [];
		$bundleConf['services'] += $f['services'] ?? [];
		
		
		$bundleConf['events'] = mergeArray($bundleConf['events'], $f['events'] ?? []);
		
		foreach ($f['assets'] ?? [] as $asset) {
			$src = $dir . $asset['from'];
			$dstPart = 'public/assets/' . $asset['to'];
			$dst = getcwd() . '/' . $dstPart;
			
			if (file_exists($dst)) {
				if (is_link($dst)) {
					unlink($dst);
				} else {
					echo "   [ERR] Cannot create link, there's already something at\n   $dst";
				}
			}
			symlink($src, $dst);
			
			addToGitIgnore($dstPart);
		}
		
		// Doesn't make sense to iterate through it yet, but some day we might compile
		// SASS, LESS, TypeScript or something like that.
		foreach ($f['include-scripts'] ?? [] as $asset) {
			$bundleConf['include-scripts'][] = $asset;
		}
		foreach ($f['include-styles'] ?? [] as $asset) {
			$bundleConf['include-styles'][] = $asset;
		}
	}
}

addToGitIgnore('config/bundles-generated.json');
file_put_contents('config/bundles-generated.json', json_encode($bundleConf, JSON_PRETTY_PRINT));

if ($gitignoreChanged) {
	file_put_contents('.gitignore', $gitignore);
}
