<?php

/**
 * @file
 * Implements bootstrap functions.
 */

// Include addon functions only if its an admin request.
if (COCKPIT_ADMIN && !COCKPIT_API_REQUEST) {
  // Extend addon functions.
  $this->module('drone')->extend([
    'fetchDeploys' => function ($limit = 50) {
      $settings = $this->app->storage->findOne('drone/settings') ?? FALSE;

      if (!$settings || !isset($settings['url'],
      $settings['owner'],
      $settings['project'],
      $settings['target'],
      $settings['token']) || !$settings['active']) {
        return [];
      }

      // $url = $settings['api_url'] . '/sites/' . $settings['site_id'] . '/deploys' . '?access_token=' . $settings['access_token'];
      $url = trim($settings['url'], "/") . '/api/repos/' . $settings['owner'] . '/' . $settings['project'] . '/builds';
      $branch = $settings['branch'] ? $settings['branch'] : 'master';

      $headers = [
        'Content-Type: application/json',
        'Accept: application/json',
        'Authorization: Bearer ' . $settings['token']
      ];

      $ch = curl_init($url);
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
      curl_setopt($ch, CURLOPT_TIMEOUT, 5);
      curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

      $deploys = [];
      $unfiltered_deploys = curl_exec($ch);
      curl_close($ch);
      $unfiltered_deploys = json_decode($unfiltered_deploys);
      $build = $settings['build'];
      $last_push = '';
      $last_promote = '';
      if ($unfiltered_deploys && is_array($unfiltered_deploys)) {
        foreach($unfiltered_deploys as $deploy) {
          if ($deploy->{target} == $branch && ($deploy->event == 'push' || ($deploy->event == 'promote' && $deploy->deploy_to == $settings['target']))) {
            // find latest successful build
            if (!$last_push && $deploy->event == 'push' && $deploy->status == 'success') {
              $last_push = $deploy->number;
            } elseif (!$last_promote) {
              $last_promote = $deploy->parent;
            }
            
            $limit--;
            if ($limit>0) {
              $deploys[] = $deploy; 
            }
          }
        }
      }

      if (!$build) {
        $build = $last_push ? $last_push : $last_promote;
      }

      // Parse dates and check if any deploy is on building status.
      $building = false;
      foreach ($deploys as $idx => $deploy) {
        $deploys[$idx]->building = false;
        if (!in_array($deploy->status, ['success', 'failure', 'error'])) {
          $building = true;
          $deploys[$idx]->building = true;
        }
        $deploys[$idx]->created_at = date('Y-m-d H:i', $deploy->created);
        $deploys[$idx]->updated_at = date('Y-m-d H:i', $deploy->updated);
        if ($deploy->finished) {
          $deploys[$idx]->deploy_time = $deploy->finished - $deploy->started;
        }
      }

      return [
        'deploys' => $deploys,
        'building' => $building,
        'build' => $build
      ];
    },
    'fetchLogs' => function ($build) {
      $settings = $this->app->storage->findOne('drone/settings') ?? FALSE;

      if (!$settings || !isset($settings['url'],
      $settings['owner'],
      $settings['project'],
      $settings['target'],
      $settings['token']) || !$settings['active']) {
        return [];
      }

      $url = trim($settings['url'], "/") . '/api/repos/' . $settings['owner'] . '/' . $settings['project'] . '/builds/'. $build;

      $headers = [
        'Content-Type: application/json',
        'Accept: application/json',
        'Authorization: Bearer ' . $settings['token']
      ];

      $logstr = "";

      $ch = curl_init($url);
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
      curl_setopt($ch, CURLOPT_TIMEOUT, 5);
      curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

      $b = curl_exec($ch);
      curl_close($ch);

      $b = json_decode($b);

      $colors = [
	      '/\\033?\[(?:0;)?30m(.*?)\\033?\[0m/s' => '<span class="black">$1</span>',
	      '/\\033?\[(?:0;)?31m(.*?)\\033?\[0m/s' => '<span class="red">$1</span>',
	      '/\\033?\[(?:0;)?32m(.*?)\\033?\[0m/s' => '<span class="green">$1</span>',
	      '/\\033?\[(?:0;)?33m(.*?)\\033?\[0m/s' => '<span class="brown">$1</span>',
	      '/\\033?\[(?:0;)?34m(.*?)\\033?\[0m/s' => '<span class="blue">$1</span>',
	      '/\\033?\[(?:0;)?35m(.*?)\\033?\[0m/s' => '<span class="purple">$1</span>',
	      '/\\033?\[(?:0;)?36m(.*?)\\033?\[0m/s' => '<span class="cyan">$1</span>',
	      '/\\033?\[(?:0;)?37m(.*?)\\033?\[0m/s' => '<span class="light-gray">$1</span>',

	      '/\\033?\[1;30m(.*?)\\033?\[0m/s' => '<span class="dark-gray">$1</span>',
	      '/\\033?\[1;31m(.*?)\\033?\[0m/s' => '<span class="light-red">$1</span>',
	      '/\\033?\[1;32m(.*?)\\033?\[0m/s' => '<span class="light-green">$1</span>',
	      '/\\033?\[1;33m(.*?)\\033?\[0m/s' => '<span class="yellow">$1</span>',
	      '/\\033?\[1;34m(.*?)\\033?\[0m/s' => '<span class="light-blue">$1</span>',
	      '/\\033?\[1;35m(.*?)\\033?\[0m/s' => '<span class="light-purple">$1</span>',
	      '/\\033?\[1;36m(.*?)\\033?\[0m/s' => '<span class="light-cyan">$1</span>',
	      '/\\033?\[1;37m(.*?)\\033?\[0m/s' => '<span class="white">$1</span>',

	      '/\\033?\[0m/s' => '',
      ];

      foreach ($b->stages as $stage) {
	      foreach ($stage->steps as $step) {

		      $logstr .= '<div class="stagename">Stage: '.$stage->name.'</div>';
		      $logstr .= '<h2 class="'.$step->status.'">'.$step->name.'</h2><br>';

		      $step_url = $url . '/logs/' . $stage->number . '/' . $step->number;
		      $ch = curl_init($step_url);
		      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
		      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
		      curl_setopt($ch, CURLOPT_TIMEOUT, 5);
		      curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
		      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

		      $logs = curl_exec($ch);
		      curl_close($ch);

		      $logs = json_decode($logs);

          $lastTime = 0;
		      foreach ($logs as $l) {
			      if (preg_match('/^\\+/', $l->out)) {
				      $logstr .= '<h3>'.htmlspecialchars($l->out).'</h3>';
			      } else {
              if ($l->time != $lastTime) {
                $logstr .= '<div class="timetext">'.$l->time.'s</div>';
                $lastTime = $l->time;
              }
				      $logstr .= preg_replace(array_keys($colors), $colors, htmlspecialchars($l->out));
			      }
		      }
	      }
      }

      return [
        'out' => $logstr
      ]; 
    },


    'createDeploy' => function ($fromBuild) {
      $settings = $this->app->storage->findOne('drone/settings');

      if (!$fromBuild || !$settings || !isset($settings['url'],
      $settings['owner'],
      $settings['project'],
      $settings['target'],
      $settings['token']) || !$settings['active']) {

        return array(
          "error" => "missing settings"
        );
      }

      $url = trim($settings['url'], "/") . '/api/repos/' . $settings['owner'] . '/' . $settings['project'] . '/builds/' . $fromBuild . '/promote?target=' . $settings['target'];

      $headers = [
        'Content-Type: application/json',
        'Accept: application/json',
        'Authorization: Bearer ' . $settings['token']
      ];

      $ch = curl_init($url);
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
      curl_setopt($ch, CURLOPT_TIMEOUT, 5);
      curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      // curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
      $result = curl_exec($ch);
      $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
      curl_close($ch);

      $decoded = json_decode($result);

      if ($httpcode >= 400) {
        $decoded->error = "ERROR: $httpcode";
      }

      return $decoded;
    },
  ]);

  // Include admin.
  include_once __DIR__ . '/admin.php';
}