<?php

include(__DIR__.'/events.php');

// Register CLI commands
$this->on('app.cli.init', function($cli) {
    $app = $this;
    include(__DIR__.'/cli.php');
});

// Detektivo api
$this->module('detektivo')->extend([

    // memoize data
    '_idxTypes' => null,

    'indexTypes' => function(?string $type = null) {

        if (!isset($this->props['_idxTypes'])) {

            $app = $this->app;

            $include = function($file) use ($app) {
                return include($file);
            };

            $types = new ArrayObject([
                'index' => $include(__DIR__.'/IndexTypes/index/config.php')
            ]);

            if ($this->app->module('content')) {
                $types['content:collection'] = $include(__DIR__.'/IndexTypes/content/config.php');
            }

            if ($this->app->module('pages')) {
                $types['pages'] = $include(__DIR__.'/IndexTypes/pages/config.php');
            }

            $this->props['_idxTypes'] = $types;

            $this->app->trigger('detektivo.collect.indextypes', [$types, $include]);
        }

        return $type ? ($this->props['_idxTypes'][$type] ?? null) : $this->props['_idxTypes'];
    },

    'createIndex' => function(string $name, array $data = []): mixed {

        if (!trim($name) || $this->exists($name)) {
            return false;
        }

        $index = array_replace_recursive([
            'name'      => $name,
            'label'     => $name,
            'info'      => '',
            'type'      => 'index',
            'fields'    => [],
            'group'     => null,
            'meta'      => null,
            '_created'  => time(),
        ], $data);

        if (!is_array($index['fields']) || !count($index['fields'])) {
            return false;
        }

        $export = $this->app->helper('utils')->var_export($index, true);

        if (!$this->app->helper('fs')->write("#storage:detektivo/{$name}.index.php", "<?php\n return {$export};")) {
            return false;
        }

        $this->app->search->createIndex("detektivo.{$name}", $index['fields']);

        return $index;
    },

    'removeIndex' => function(string $name): bool {

        if (!$this->exists($name)) {
            return false;
        }

        $this->app->helper('fs')->delete("#storage:detektivo/{$name}.index.php");
        $this->app->search->removeIndex("detektivo.{$name}");

        $this->app->trigger('detektivo.remove.index', [$name]);

        return true;
    },

    'exists' => function(string $name): ?string {
        return $this->app->path("#storage:detektivo/{$name}.index.php");
    },

    'index' => function(string $name, bool $indexCheck = false): mixed {

        if (!$this->exists($name)) {
            return null;
        }

        if ($indexCheck && !$this->app->search->exists("detektivo.{$name}")) {
            $this->app->search->createIndex("detektivo.{$name}", $this->indexes($name)['fields']);
        }

        return $this->app->search->index("detektivo.{$name}");
    },

    'indexes' => function(?string $name = null): ?array {

        $indexes = [];

        foreach ($this->app->helper('fs')->ls('*.index.php', '#storage:detektivo') as $file) {

            $store = include($file->getPathName());

            $indexes[$store['name']] = $store;
        }

        return $name ? ($indexes[$name] ?? null) : $indexes;
    },

    // indexer related methods

    'runIndexer' => function($name, $meta = []) {

        $index = $this->indexes($name);

        if (!$index) {
            return false;
        }

        $type = $this->indexTypes($index['type']);

        if (!$type || !isset($type['index'])) {
            return true;
        }

        $indexer = new \Detektivo\Helper\Indexer($name, $this->app);

        $indexer->start($meta);

        return true;
    },

    'isIndexerRunning' => function($name) {
        return $this->app->dataStorage->keyExists('detektivo/indexer', $name);
    },

    'getIndexerLog' => function($name) {
        return $this->app->dataStorage->getKey('detektivo/indexer', $name, []);
    },
]);
