<?php

namespace App\Services;

class GithubService
{
    private $cacheFile = null;
    private $config = [];

    public function __construct()
    {
        $this->config = config('services.github');
        $this->cacheFile = storage_path('app/github_cache.txt');
    }

    public function checkForLatestRelease()
    {
        $releaseInfo = [];
        $etag = '';

        if ($this->doesCacheExist())
        {
            // Get the etag from the cache
            $cacheData = $this->getCacheData();
            $etag = $cacheData->latest_release->etag;
            $releaseInfo = $cacheData->latest_release->release_info;
        }

        // Lookup and store the version information
        $statusCode = -1;
        $result = $this->getLatestReleaseFromGithub($etag, $statusCode);

        if ($statusCode == 200)
        {
            // Store the etag (in HTTP headers) for future reference
            $matches = [];
            $etag = '';
            if (preg_match('/^etag: "(.+)"/mi', $result[0], $matches))
            {
                $etag = $matches[1];
            }

            $releaseInfo = json_decode($result[1]);
        }

        if (!empty($etag))
        {
            $this->setCacheData([
                'latest_release' => [
                    'etag' => $etag,
                    'release_info' => $releaseInfo
                ]
            ]);
        }

        return $releaseInfo;
    }

    private function doesCacheExist()
    {
        return file_exists($this->cacheFile);
    }

    private function getCacheData()
    {
        return json_decode(file_get_contents($this->cacheFile));
    }

    private function getLatestReleaseFromGithub($etag = '', &$statusCode)
    {
        $httpHeaders = [
            sprintf('User-Agent: pandy06269/blue-twilight (v%s)', config('app.version'))
        ];

        if (!empty($etag))
        {
            $httpHeaders[] = sprintf('If-None-Match: "%s"', $etag);
        }

        $ch = curl_init($this->config['latest_release_url']);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeaders);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch);

        if ($result === false)
        {
            throw new \Exception(sprintf('Error from Github: %s', curl_error($ch)));
        }

        $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        return explode("\r\n\r\n", $result, 2);
    }

    private function setCacheData(array $data)
    {
        file_put_contents($this->cacheFile, json_encode($data));
    }
}