<?php

require_once "init.php";

require_once BASE . "/lib/mysql.php";

$uri_parts = explode('/', $_SERVER['REQUEST_URI']);

if ($uri_parts[0] != '' || $uri_parts[1] != 'feeds')
  throw_http_error(422, 'Unprocessable Entity');

$last = array_pop($uri_parts);
if ($last != '')
  array_push($uri_parts, $last);

array_splice(
  $uri_parts,
  0, 2
);

if (count($uri_parts) == 0) { // index page

  require_once BASE . "/lib/style.php";
  require_once BASE . "/lib/format.php";

  print_header("RSS - Feeds");

  $result = mysql_run_query(
    "SELECT DISTINCT `architectures`.`name` FROM `architectures`" .
    mysql_join_architectures_repositories() .
    " WHERE `repositories`.`is_on_master_mirror`" .
    " ORDER BY `name`"
  );
  $archs = array();
  while ($row = $result -> fetch_assoc())
    $archs[$row['name']] = $row['name'] . '/';

  $print_archs = array_merge(
    array(
      '' => '',
      'All Arches' => 'all/'
    ),
    $archs
  );

  $result = mysql_run_query(
    "SELECT DISTINCT `repositories`.`name` FROM `repositories` WHERE `repositories`.`is_on_master_mirror` ORDER BY `name`"
  );
  $repos = array();
  while ($row = $result -> fetch_assoc())
    $repos[$row['name']] = $row['name'] . '/';

  $print_repos = array_merge(
    array(
      'All Repos' => ''
    ),
    $repos
  );

  $bugtracker_projects = array(
    0 => 'All Projects',
    1 => 'Arch Linux 32'
  );

  $bugtracker_operations = array(
    'Opened' => '',
    'Edited' => 'topic=edit&',
    'Closed' => 'topic=clo&'
  );

  function print_arches_header() {
    global $print_archs;
    foreach ($print_archs as $arch => $dummy) {
      print "                <th>\n";
      print "                  " . $arch . "\n";
      print "                </th>\n";
    };
  }

  function print_feeds($prefix) {
    global $print_archs;
    global $print_repos;
    foreach ($print_repos as $repo => $dummy) {
      print "              <tr>\n";
      print "                <td>\n";
      print "                  <strong>" . $repo . "</strong>\n";
      print "                </td>\n";
      foreach ($print_archs as $arch => $dummy) {
        if ($arch == '')
          continue;
        print "                <td>\n";
        print "                  <a href=\"/feeds/packages/" . $prefix . $print_archs[$arch] . $print_repos[$repo] . "\" class=\"rss\">Feed</a>\n";
        print "                </td>\n";
      }
      print "              </tr>\n";
    }
  }

  function print_feeds_table($prefix) {
    print "          <table class=\"pretty2\">\n";
    print "            <thead>\n";
    print "              <tr>\n";
    print_arches_header();
    print "              </tr>\n";
    print "            </thead>\n";
    print "            <tbody>\n";
    print_feeds($prefix);
    print "            </tbody>\n";
    print "          </table>\n";
  }

  ?>
        <div id="rss-feeds" class="box">
          <h2>
            RSS Feeds
          </h2>
          <p>
            Several RSS feeds are available for consumption from the Arch32 website.
            The majority of these are package-related and allow feeds to be customized for the updates you care about.
          </p>
          <h3>
            News Feed
          </h3>
          <p>
            Grab the
            <a href="https://bbs.archlinux32.org/extern.php?action=feed&fid=12&type=atom" class="rss" title="Arch Linux news feed">news item feed</a>
            to keep up-to-date with the latest news from the Arch Linux development staff.
          </p>
          <h3>
            Package Feeds
          </h3>
          <p>
            If you are interested in
            <a href="/feeds/packages/" class="rss" title="Arch Linux 32 package updates feed">all package updates</a>,
            then grab this feed.
  <?php

  print_feeds_table('');

  ?>
            <p>
              <s>Recently added packages.</s> (to be implemented)
            </p>
  <?php

  // print_feeds_table('added/');

  ?>
            <p>
              <s>Recently removed packages.</s> (to be implemented)
            </p>
  <?php

  // print_feeds_table('removed/');

  ?>
            <h3>
              Release Feed
            </h3>
            <p><strike>
              Grab the
              <a href="/feeds/releases/" class="rss" title="Arch Linux release feed">ISO release feed</a>
              if you want to help seed the ISO release torrents as they come out.
              </strike>
            </p>
            <h3>
              Development Feeds
            </h3>
            <p>
              Subscribe to any of the following to track bug tickets and feature requests from the
              <a href="https://bugs.archlinux32.org/" title="Arch Linux 32 Bugs">Arch Linux 32 Bugtracker</a>:
            </p>
            <table class="pretty2">
              <thead>
                <tr>
                  <th>
                    Project
                  </th>
  <?php

  foreach ($bugtracker_operations as $label => $dummy) {
    print "                <th>\n";
    print "                  Recently " . $label . " Tasks\n";
    print "                </th>\n";
  }

  ?>
                </tr>
              </thead>
              <tbody>
  <?php

  foreach ($bugtracker_projects as $id => $project) {
    print "              <tr>\n";
    print "                <td>\n";
    print "                  " . $project . "\n";
    print "                </td>\n";
    foreach ($bugtracker_operations as $label => $option) {
      print "                <td>\n";
      print "                  <a href=\"https://bugs.archlinux32.org/feed.php?feed_type=rss2&" . $option . "project=" . $id . "\" class=\"rss\">Feed</a>\n";
      print "                </td>\n";
    }
    print "              </tr>\n";
  }

  ?>
              </tbody>
            </table>
          </div>
  <?php

  print_footer();

  die();

} // index page

if ($uri_parts[0] == 'releases') {
  if (count($uri_parts) != 1)
    throw_http_error(501, "Not Implemented", '/feeds/' . implode('/',$uri_parts));
  $available_isos = apcu_fetch('available_isos', $apcu_success);
  if ($apcu_success == false || true) {
    $ch = curl_init("https://mirror.archlinux32.org/archisos/");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $listing = curl_exec($ch);
    curl_close($ch);
    preg_match_all(
      ',<a href="(archlinux-([0-9]{4}\.[0-9]{2}\.[0-9]{2})-([^.]+)\.iso)">\1</a>\s+(\S+)\s+\S+\s+([0-9]+)\s*\n,',
      $listing,
      $matches,
      PREG_SET_ORDER
    );
    $available_isos = array();
    foreach ($matches as $match) {
      $available_isos[] = array(
        'file' => $match[1],
        'title' => $match[2] . '-' . $match[3],
        'build_date' => strtotime(str_replace('.', '-', $match[2])),
        'build_type' => $match[3],
        'release_date' => $match[4],
        'size' => $match[5]
      );
    }
    apcu_store('available_isos', $available_isos, 3600);
  }

  header('Content-Type: application/rss+xml; charset=utf-8');
  print "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
  print "<rss version=\"2.0\">";
  print "<channel>";
  print "<title>";
  print "Arch Linux 32: Releases";
  print "</title>";
  print "<link>";
  print "https://www.archlinux32.org/download/";
  print "</link>";
  print "<description>";
  print "Release ISOs";
  print "</description>";
  print "<language>";
  print "en-us";
  print "</language>";
  print "<lastBuildDate>";
  print date('Y-m-d', $available_isos[0]['build_date']);
  print "</lastBuildDate>";
  foreach ($available_isos as $available_iso) {
    print "<item>";
    print "<title>";
    print $available_iso['title'];
    print "</title>";
    // TODO: link to iso description (do we want that?)
    print "<description>";
    print "</description>";
    print "<pubDate>";
    print date('Y-m-d', $available_iso['release_date']);
    print "</pubDate>";
    // TODO: guid
    print "<enclosure length=\"";
    print date('Y-m-d', $available_iso['size']);
    print "\" type=\"application/x-bittorrent\">";
    // TODO: url=\"https://www.archlinux32.org/iso/2019.02.01/archlinux-2019.02.01-x86_64.iso.torrent\">";
    print "</enclosure>";
    print "</item>";
  }
  print "</channel>";
  print "</rss>";

  die();
} // releases

if ($uri_parts[0] == 'packages') {

  array_splice(
    $uri_parts,
    0, 1
  );

// TODO: implement "added" and "removed" - but how?
//  $actions = array('' => '', 'added' => 'added', 'removed' => 'removed');
  $actions = array('' => '');
  $archs = array('all' => 'all');
  $result = mysql_run_query(
    "SELECT DISTINCT `architectures`.`name` FROM `architectures`" .
    mysql_join_architectures_repositories() .
    " WHERE `repositories`.`is_on_master_mirror`" .
    " ORDER BY `name`"
  );
  while ($row = $result -> fetch_assoc())
    $archs[$row['name']] = $row['name'];
  $repos = array('' => '');
  $result = mysql_run_query(
    "SELECT DISTINCT `repositories`.`name` FROM `repositories` WHERE `repositories`.`is_on_master_mirror` ORDER BY `name`"
  );
  while ($row = $result -> fetch_assoc())
    $repos[$row['name']] = $row['name'];

  if (count($uri_parts) > 0 && array_key_exists($uri_parts[0], $actions)) {
    $action = $uri_parts[0];
    $action_filter = 'unimplemented';
    array_splice(
      $uri_parts,
      0, 1
    );
  }
  else {
    $action = '';
    $action_filter = '`repositories`.`is_on_master_mirror`';
  }

  if (count($uri_parts) > 0) {
    if (!array_key_exists($uri_parts[0], $archs))
      throw_http_error(501, "Not Implemented", implode('/',$uri_parts));
    $arch = $uri_parts[0];
    $arch_filter = ' AND `r_a`.`name`="' . $arch . '"';
    array_splice(
      $uri_parts,
      0, 1
    );
  }
  else {
    $arch = '';
    $arch_filter = '';
  }

  if (count($uri_parts) > 0) {
    if (!array_key_exists($uri_parts[0], $repos))
      throw_http_error(501, "Not Implemented", implode('/',$uri_parts));
    $repo = $uri_parts[0];
    $repo_filter = ' AND `repositories`.`name`="' . $repo . '"';
    array_splice(
      $uri_parts,
      0, 1
    );
  }
  else {
    $repo = '';
    $repo_filter = '';
  }

  if (count($uri_parts) != 0)
    throw_http_error(501, "Not Implemented", implode('/',$uri_parts));

  $result = mysql_run_query(
    "SELECT MAX(`build_assignments`.`return_date`) AS `max_build_date`" .
    " FROM `build_assignments`" .
    mysql_join_build_assignments_binary_packages() .
    mysql_join_binary_packages_binary_packages_in_repositories() .
    mysql_join_binary_packages_in_repositories_repositories() .
    mysql_join_repositories_architectures("", "r_a") .
    " WHERE " . $action_filter . $repo_filter . $arch_filter
  );
  $max_build_date = $result -> fetch_assoc();
  $max_build_date = $max_build_date['max_build_date'];

  $result = mysql_run_query(
    "SELECT `binary_packages`.`pkgname`," .
    "`binary_packages`.`epoch`," .
    "`binary_packages`.`pkgver`," .
    "`binary_packages`.`pkgrel`," .
    "`binary_packages`.`sub_pkgrel`," .
    "`binary_packages`.`sub_pkgrel_omitted`," .
    "`architectures`.`name` AS `architecture`," .
    "`repositories`.`name` AS `repo`," .
    "`r_a`.`name` AS `r_a`," .
    "`binary_packages_in_repositories`.`last_moved`" .
    " FROM `binary_packages`" .
    mysql_join_binary_packages_binary_packages_in_repositories() .
    mysql_join_binary_packages_in_repositories_repositories() .
    mysql_join_repositories_architectures("", "r_a") .
    mysql_join_binary_packages_architectures() .
    " WHERE " . $action_filter . $repo_filter . $arch_filter .
    " ORDER BY `binary_packages_in_repositories`.`last_moved` DESC" .
    " LIMIT 50"
  );
  $packages = array();
  while ($row = $result -> fetch_assoc())
    $packages[] = $row;

  header('Content-Type: application/rss+xml; charset=utf-8');

  print "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
  print "<rss version=\"2.0\">";
  print "<channel>";
  print "<title>";
  print "Arch Linux 32: ";
  switch ($action) {
    case '':
      print "Recent package updates";
      break;
    case 'added':
      print "Recent added packages";
      break;
    case 'removes':
      print "Recent removed packages";
      break;
  }
  if ($arch != 'all')
    print " (" . $arch;
  if ($repo != '')
    print " [" . $repo . "]";
  if ($arch != '')
    print ")";
  print "</title>";
  print "<link>";
  print "https://www.archlinux32.org/packages/";
  print "</link>";
  print "<description>";
  switch ($action) {
    case '':
      print "Recently updated packages in the Arch Linux 32 package repositories";
      break;
    case 'added':
      print "Recently added packages to the Arch Linux 32 package repositories";
      break;
    case 'removes':
      print "Recently removed packages from the Arch Linux 32 package repositories";
      break;
  }
  if ($arch != 'all')
    print " for the '" . $arch . "' architecture (including 'any' packages)";
  else
    print " for all architectures";
  if ($repo != '')
    print " in the [" . $repo . "] repository";
  print ".";
  print "</description>";
  print "<language>";
  print "en-us";
  print "</language>";
  print "<lastBuildDate>";
  print $max_build_date;
  print "</lastBuildDate>";
  foreach ($packages as $package) {
    print "<item>";
    print "<title>";
    print $package['pkgname'];
    if ($package['epoch'] != 0)
      print $package['epoch'] . ":";
    print $package['pkgver'] . "-" . $package['pkgrel'];
    if (!$package['sub_pkgrel_omitted'])
      print '.' . $package['sub_pkgrel'];
    print ' ' . $package['architecture'];
    print "</title>";
    print "<link>";
    print "https://www.archlinux32.org/packages/" . $package['repo'] . "/" . $package['r_a'] . "/" . $package['pkgname'] . "/";
    print "</link>";
// TODO: description
    print "<pubDate>";
    print $package['last_moved'];
    print "</pubDate>";
// TODO: guid
    print "<category>";
    print $package['repo'];
    print "</category>";
    print "<category>";
    print $package['r_a'];
    print "</category>";
    print "</item>";
  }
  print "</channel>";
  print "</rss>";

  die();

} // packages

throw_http_error(501, "Not Implemented");