<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

use App\Traits\ParseNodes;
use App\Classes\FTNPacket;
use App\Models\{Echomail,Netmail,Zone};

class ImportPacket extends Command
{
	use ParseNodes;

	/**
	 * The name and signature of the console command.
	 *
	 * @var string
	 */
	protected $signature = 'import:pkt {file : Packet File} {--f|force : Force import of duplicates}';

	/**
	 * The console command description.
	 *
	 * @var string
	 */
	protected $description = 'Import Mail Packet';

	/**
	 * Create a new command instance.
	 *
	 * @return void
	 */
	public function __construct()
	{
		parent::__construct();
	}

	/**
	 * Execute the console command.
	 *
	 * @return mixed
	 * @throws \Exception
	 */
	public function handle()
	{
		$pkt = new FTNPacket($this->argument('file'));

		foreach ($pkt->messages as $o)
		{
			$o->date->setTimezone(($o->tzutc >= 0 ? '+' : '').substr_replace($o->tzutc,':',2,0));

			switch ($o->type)
			{
				case 'echomail':
					// See if we already have this message.
					$oo = Echomail::firstOrNew([
						'date'=>$o->date,
						'from_ftn'=>$this->get_node(['z'=>$o->fz,'n'=>$o->fn,'f'=>$o->ff,'p'=>$o->fp])->id,
						'msgid'=>$o->msgid,
					]);

					if (md5(utf8_decode($eo->message)) == md5($o->message))
					{
						$this->warn(sprintf('Duplicate message: %s@%s with id: %s',$o->from,$o->fqfa,$o->msgid));
						break 2;
					}

					break;

				case 'netmail':
					// See if we already have this message.
					$oo = Netmail::firstOrNew([
						'date'=>$o->date,
						'from_ftn'=>$this->get_node(['z'=>$o->fz,'n'=>$o->fn,'f'=>$o->ff,'p'=>$o->fp])->id,
						'msgid'=>$o->msgid,
					]);

					$oo->to_ftn = $this->get_node(['z'=>$o->tz,'n'=>$o->tn,'f'=>$o->tf,'p'=>$o->tp])->id;

					break;

				default:
					abort(500,'Unknown type: '.$o->type);
			}

			if (md5(utf8_decode($oo->message)) == md5($o->message))
			{
				$this->warn(sprintf('Duplicate message: %s@%s with id: %s',$o->from,$o->fqfa,$o->msgid));
				if (! $this->option('force'))
					continue;
			}

			$oo->pkt_from = $this->get_node(['z'=>$pkt->sz,'n'=>$pkt->sn,'f'=>$pkt->sf,'p'=>$pkt->sp])->id;
			$oo->pkt_to = $this->get_node(['z'=>$pkt->dz,'n'=>$pkt->dn,'f'=>$pkt->df,'p'=>$pkt->dp])->id;
			$oo->pkt = $pkt->filename;
			$oo->pkt_date = $pkt->date;
			$oo->flags = $o->flags;
			$oo->cost = $o->cost;
			$oo->from_user = utf8_encode($o->from);
			$oo->to_user = utf8_encode($o->to);
			$oo->subject = utf8_encode($o->subject);
			$oo->tz = $o->tzutc;
			$oo->replyid = $o->replyid;
			$oo->message = utf8_encode($o->message);
			$oo->origin = utf8_encode($o->origin);
			$oo->save();

			foreach ($o->kludge as $k=>$v)
			{
				$oo->kludges()->attach($k,['value'=>json_encode($v)]);
			}

			foreach ($o->unknown as $v)
			{
				$oo->kludges()->attach('UNKNOWN',['value'=>json_encode($v)]);
			}

			// Finish off the import
			switch($o->type) {
				case 'echomail':
					foreach ($o->seenby as $v)
					{
						foreach ($this->parse_nodes(Zone::findOrFail($pkt->sz),$v) as $no)
						{
							$oo->seenbys()->attach($no->id);
						}
					}

					$seq = 0;
					foreach ($o->path as $v)
					{
						foreach ($this->parse_nodes(Zone::findOrFail($pkt->sz),$v) as $no)
						{
							$oo->paths()->attach($no->id,['sequence'=>$seq++]);
						}
					}

					break;

				case 'netmail':
					$seq = 0;

					foreach ($o->via as $v)
					{
						$data = preg_split('/\s/',$v);
						$ftno = $this->get_node(ftn_address_split($data[0]));
						unset($data[0]);

						$oo->paths()->attach($ftno->id,['sequence'=>$seq++,'value'=>json_encode($data)]);
					}

					break;
			}
		}
	}
}