<?php

namespace Ignite\Core\Models\Import;

use Ignite\Core\Entities\Import;
use Ignite\Extensions\Monolog\Reader\LogReader;
use Illuminate\Contracts\Config\Repository;

class LogFormatter
{
    /**
     * @var Import
     */
    protected $import;

    /**
     * @var Repository
     */
    private $config;

    /**
     * ImportLogFormatter constructor.
     *
     * @param Import $import
     * @param Repository $config
     */
    public function __construct(Import $import, Repository $config)
    {
        $this->import = $import;
        $this->config = $config;
    }

    /**
     * Format each line of the log file.
     *
     * @return \Illuminate\Support\Collection
     */
    public function format()
    {
        $reader = new LogReader(
            $this->import->getLogPath(),
            $this->pattern()
        );

        return collect(iterator_to_array($reader))->filter()->map(function ($log) {
            return [
                'date' => $this->formatDate($log),
                'icon' => $this->formatIcon($log),
                'type' => $this->formatType($log),
                'color' => $this->formatColor($log),
                'message' => $this->formatMessage($log),
                'context' => $this->formatContext($log),
            ];
        });
    }

    /**
     * Format the date.
     *
     * @param array $log
     * @return mixed
     */
    private function formatDate($log)
    {
        return $log['date']->format('Y-m-d h:i:s');
    }

    /**
     * Format the icon based on the level.
     *
     * @param array $log
     * @return string
     */
    private function formatIcon($log)
    {
        $level = strtolower($log['level']);

        switch ($level) {
            case 'error':
                return 'exclamation-circle';
            case 'info':
                return 'check';
            default:
                return 'info';
        }
    }

    /**
     * Format the correct color based on the level.
     *
     * @param array $log
     * @return string
     */
    private function formatColor($log)
    {
        $level = strtolower($log['level']);

        switch ($level) {
            case 'error':
                return 'text-danger';
            case 'info':
                return 'text-green';
            default:
                return 'text-muted';
        }
    }

    /**
     * Format the message type.
     *
     * @param array $log
     * @return string
     */
    private function formatType($log)
    {
        $type = strtolower($log['level']);

        if ($type === 'info') {
            return 'Success';
        }

        return ucwords($type);
    }

    /**
     * Format the message.
     *
     * @param array $log
     * @return string
     */
    private function formatMessage($log)
    {
        return $log['message'];
    }

    /**
     * Format the context data.
     *
     * @param array $log
     * @return string
     */
    private function formatContext($log)
    {
        return $log['context'] ?? '';
    }

    /**
     * The pattern to parse the log line.
     *
     * @return mixed
     */
    private function pattern()
    {
        $default = '/\[(?P<date>.*)\] (?P<logger>\w+).(?P<level>\w+): (?P<message>.+) (?P<context>[\[\{].*[\]\}]) (?P<extra>[\[\{].*[\]\}])/';

        return $this->config->get('core.import.reader.pattern', $default);
    }
}
