<?php
/*
 * FedoraClient is a PHP classe to interact with web services
 * 
 * Copyright (C) 2010  Remi Collet
 * http://github.com/remicollet/rpmphp.
 * 
 * Inspired from python-fedora
 * 
 * FedoraClient is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * python-fedora is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * See <http://www.gnu.org/licenses/>
 *
 */

define ('FEDORACLIENT_VERSION','0.1');

if (!function_exists('curl_version')) {
   die("curl extention required\n");
}

abstract class FedoraClient {
   private $url;
   private $agent;
   protected $debug = 0;
   
   function __construct ($url, array $options) {
      $this->url = $url;
      if (isset($options['agent']) && !empty($options['agent'])) {
         $this->agent = $options['agent'];
      } else {
         $this->agent = 'PHP FedoraClient/'.FEDORACLIENT_VERSION;
      }
      if (isset($options['debug']) && intval($options['debug'])>0) {
         $this->debug = intval($options['debug']);
      } 
      if ($this->debug >= 2) {
         echo "[debug] ".__CLASS__."::".__FUNCTION__.": url='$url', agent='".$this->agent."'\n";
      }
   }   
   
   function sendRequest($method, array $options=array()) {
      $curl = curl_init();
        # And join to make our url.
      $url = $this->url.urlencode($method);
      curl_setopt($curl, CURLOPT_URL, $url);
        # Boilerplate so pycurl processes cookies
      curl_setopt($curl, CURLOPT_COOKIEFILE, '/dev/null');

        # Associate with the response to accumulate data
      $this->data='';
      curl_setopt($curl, CURLOPT_WRITEFUNCTION, array($this, 'receive'));

        # Follow redirect
      curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
      curl_setopt($curl, CURLOPT_MAXREDIRS, 5);
      
        # Set standard headers
      curl_setopt($curl, CURLOPT_HTTPHEADER, array('User-agent: '.$this->agent, 'Accept: application/json'));

      if ($this->debug >= 1) {
         echo "[debug] ".__CLASS__."::".__FUNCTION__.": call '$url'\n";
      }
        # run the request
      curl_exec($curl);

   
        # Check for auth failures
        # Note: old TG apps returned 403 Forbidden on authentication failures.
        # Updated apps return 401 Unauthorized
        # We need to accept both until all apps are updated to return 401.
      $http_status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
      if ($http_status==401 || $http_status==403) { 
         if ($this->debug >= 1) {
            echo "[debug] ".__CLASS__."::".__FUNCTION__.": http_status '$http_status' Authentication failed logging in\n";
         }
         return array();
      } else if ($http_status>=400) {
         if ($this->debug >= 1) {
            echo "[debug] ".__CLASS__."::".__FUNCTION__.": http_status '$http_status' Unknown HTTP Server Response\n";
         }
         return array();
      } else if ($this->debug >= 2) {
         echo "[debug] ".__CLASS__."::".__FUNCTION__.": http_status '$http_status'\n";
      }
      
      if ($this->debug >= 1) {
         echo "[debug] ".__CLASS__."::".__FUNCTION__.": close connexion\n";
      }
      curl_close($curl);
      return json_decode($this->data, true);
   }
   
   function receive($curl, $data) {
      if ($this->debug >= 9) {
         echo "[debug] ".__CLASS__."::".__FUNCTION__.": $data\n";
      }
      $this->data .= $data;
      return strlen($data);
   }
}



class FedoraPkgdb extends FedoraClient {
   private $branches = array();
   
   function __construct (array $options=array()) {
      parent::__construct('https://admin.fedoraproject.org/pkgdb/', $options);
      if ($this->debug>=2) {
         echo "[debug] ".__CLASS__."::".__FUNCTION__."\n";
      }
   }
   
   function getBranches($refresh=false) {
      if (count($this->branches) && !$refresh) {
         return $this->branches;
      }
      $rep  =$this->sendRequest('collections');

      if (isset($rep['collections'])) {
         $this->branches = array();
         foreach ($rep['collections'] as $coll) if (isset($coll[0]['branchname'])) {
            $this->branches[$coll[0]['branchname']] = $coll[0];
         }
      }
      return $this->branches;
   }
}
?>