<?php

namespace RtmMail;

use Monolog\Logger;

/**
 * EventListener - Custom listener for error/debug logging
 */
class EventListener
{
    /**
     * CHANNEL_NAME - Custom name for Wonolog log channels
     */
    const CHANNEL_NAME = 'RTMMAIL';

    /**** Hook Callback Methods ****/

    /**
     * migration_success - hook callback for when a migration class succeeded
     * @param $migration_class
     */
    public function migration_success($migration_class)
    {
        $source = $this->get_source();
        do_action('wonolog.log', [
            'message' => "Migration of class <code>{$migration_class}</code> was successful",
            'channel' => self::CHANNEL_NAME,
            'level' => Logger::INFO,
            'context' => compact('migration_class', 'source'),
        ]);
    }

    /**
     * migration_failed - hook callback for when a migration class fails
     * @param $migration_class
     * @param $error
     */
    public function migration_failed($migration_class, $error)
    {
        $source = $this->get_source();
        do_action('wonolog.log', [
            'message' => "Migration of class <code>{$migration_class}</code> failed because of an error: {$error}",
            'channel' => self::CHANNEL_NAME,
            'level' => Logger::ERROR,
            'context' => compact('migration_class', 'source'),
        ]);
    }

    /**
     * log_deleted - hook callback when a mail log gets deleted by a user
     * @param $log_id
     * @param $user_id
     */
    public function log_deleted($log_id, $user_id)
    {
        $source = $this->get_source();
        $user_data = get_user_by('id', $user_id);
        do_action('wonolog.log', [
            'message' => "Email Log (#{$log_id}) has been deleted by {$user_data->display_name}",
            'channel' => self::CHANNEL_NAME,
            'level' => Logger::DEBUG,
            'context' => compact('log_id', 'user_id', 'source'),
        ]);
    }

    /**
     * log_edited - hook callback when a mail log gets edited by a user
     * @param $log_id
     * @param $user_id
     */
    public function log_edited($log_id, $user_id)
    {
        $user_data = get_user_by('id', $user_id);
        $source = $this->get_source();
        do_action('wonolog.log', [
            'message' => "{$user_data->display_name} edited Email Log: #{$log_id}",
            'channel' => self::CHANNEL_NAME,
            'level' => Logger::DEBUG,
            'context' => compact('log_id', 'user_id', 'source'),
        ]);
    }

    /**
     * send_failed - hook callback for when an email fails to be sent
     * @param $log_id
     * @param $error
     */
    public function send_failed($log_id, $error)
    {
        $source = $this->get_source();
        do_action('wonolog.log', [
            'message' => "Failed to send email (#{$log_id}): {$error}",
            'channel' => self::CHANNEL_NAME,
            'level' => Logger::ERROR,
            'context' => compact('log_id', 'error', 'source'),
        ]);
    }

    /**
     * send_success - hook callback for when an email has been sent
     * @param $log_id
     */
    public function send_success($log_id)
    {
        $source = $this->get_source();
        do_action('wonolog.log', [
            'message' => "Email with log id {$log_id} has been sent",
            'channel' => self::CHANNEL_NAME,
            'level' => Logger::INFO,
            'context' => compact('log_id', 'source'),
        ]);
    }

    /**
     * mail_caught - hook callback for when an email has been caught
     * @param $log_id
     */
    public function mail_caught($log_id)
    {
        $source = $this->get_source();
        $request = [
            'HEADERS' => getallheaders(),
            'POST' => $_POST,
            'GET' => $_GET,
        ];
        do_action('wonolog.log', [
            'message' => "Mail has been logged",
            'channel' => self::CHANNEL_NAME,
            'level' => Logger::INFO,
            'context' => compact('log_id', 'source', 'request'),
        ]);
    }

    /**
     * mail_queued - hook callback for when an email log has been queued
     * @param $log_id
     * @param $date_str
     */
    public function mail_queued($log_id, $date_str)
    {
        $source = $this->get_source();
        do_action('wonolog.log', [
            'message' => "Log (#{$log_id}) has been queued for {$date_str}",
            'channel' => self::CHANNEL_NAME,
            'level' => Logger::INFO,
            'context' => compact('log_id', 'source', 'date_str'),
        ]);
    }

    /**
     * mail_queue_removed - hook callback for when an email log has been queued
     * @param $log_id
     * @param $date_str
     */
    public function mail_queue_removed($log_id)
    {
        $source = $this->get_source();
        do_action('wonolog.log', [
            'message' => "{$source} has removed mail log (#{$log_id}) from the queue",
            'channel' => self::CHANNEL_NAME,
            'level' => Logger::DEBUG,
            'context' => compact('log_id', 'source'),
        ]);
    }

    /**
     * text_message_exception - hook callback for when sending a text message failed
     * @param $log_id
     * @param $error
     */
    public function text_message_exception($log_id, $error)
    {
        $source = $this->get_source();
        do_action('wonolog.log', [
            'message' => "Failed sending text message for log {$log_id} because of a Twilio error",
            'channel' => self::CHANNEL_NAME,
            'level' => Logger::ERROR,
            'context' => compact('log_id', 'source', 'error'),
        ]);
    }

    /**
     * get_source - Retrieve the source (user or IP) of the event
     * @return mixed|string - User string or IP-address
     */
    private function get_source()
    {
        if (is_user_logged_in()) {
            $user = wp_get_current_user();
            return $user->display_name . ' (ID: ' . $user->ID . ')';
        } else {
            $source = $_SERVER['REMOTE_ADDR'];
            if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
                $source = $_SERVER['HTTP_CLIENT_IP'];
            } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                $source = $_SERVER['HTTP_X_FORWARDED_FOR'];
            }
            return $source;
        }
    }
}