<?php

/**
 * Import from files
 */
namespace App\Traits;

use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

use App\Models\File;

trait Import
{
	protected Collection $_columns; // Columns in the Import File

	/**
	 * Count the lines in a file
	 * Assumes $file is compressed with ZIP
	 */
	private function getFileLines(string $file): int
	{
		$c = 0;

		$f = NULL;
		$z = $this->openFile($file,$f);

		while (! feof($f)) {
			fgets($f);
			$c++;
		}

		fclose($f);

		return $c;
	}

	// @todo Consider merging this with File::openZipFile
	private function openFile(string $file,&$f): \ZipArchive
	{
		$z = new \ZipArchive;

		if ($z->open($file)) {
			if ($z->count() !== 1)
				throw new \Exception(sprintf('%s:File [%s] has more than 1 file (%d)', self::LOGKEY, $file, $z->count()));

			$zipfile = $z->statIndex(0, \ZipArchive::FL_UNCHANGED);
			Log::debug(sprintf('%s:Looking at [%s] in archive [%s]', self::LOGKEY,$zipfile['name'],$file));

			$f = $z->getStream($zipfile['name']);
			if (! $f)
				throw new \Exception(sprintf('%s:Failed getting ZipArchive::stream (%s)',self::LOGKEY,$z->getStatusString()));
			else
				return $z;

		} else {
			throw new \Exception(sprintf('%s:Failed opening ZipArchive [%s] (%s)',self::LOGKEY,$file,$z->getStatusString()));
		}
	}

	/**
	 * Return the columns from the file that we'll work with
	 *
	 * @param string $line
	 * @return Collection
	 */
	private function getColumns(string $line): Collection
	{
		$this->_columns = collect(explode(',',strtoupper($line)))->filter();
		return $this->_columns->intersect($this->columns);
	}

	/**
	 * Get the index for the column in the file
	 *
	 * @param string $key
	 * @return int|null
	 */
	private function getColumnKey(string $key): ?int
	{
		return ($x=$this->_columns->search(strtoupper($this->columns->get($key)))) !== FALSE ? $x : NULL;
	}

	private function getFileFromHost(string $key,File $file): string
	{
		$path = sprintf('import/%s.%d',$key,$file->id);

		Storage::disk('local')->put($path,Storage::get($file->full_storage_path));

		return Storage::disk('local')->path($path);
	}
}