#!/usr/local/bin/php -q
<?/*
Copyright (C) 2003 Media Net Link, Inc. Danville, CA 94526 USA

This file is part of AthenaRMS.

AthenaRMS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

AthenaRMS 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/?>
<?
  echo "Welcome to Athena 5 Installation!\n\n";
  $basedir = dirname(preg_replace('/\/\.$/', '', 
    getcwd() . '/' . dirname($_SERVER['PHP_SELF'])));

  if (!chdir($basedir))
    die("Couldn't cd to basedir '$basedir'\n");

  if (!file_exists('athena.conf'))
    die("Please copy athena.conf.sample to athena.conf and edit for your\n"
      . "system's configuration, then run install.php again\n");

  require_once 'athena.conf';
  $driver = $db_config['driver'];

  if ($basedir != $athena_root)
    echo("warning: installed directory ('$basedir') does not match "
       ."\$athena_root ('$athena_root') from $basedir/athena.conf\n");

  if (!preg_match('/^(pgsql|mysql|oci8)$/', $driver))
    die("error: \$db_config['driver'] must be set to pgsql, mysql, or oci8\n"
       ."\t(is currently '$driver')\n");

  if (!strlen($db_config['dbname']))
    die("error: \$db_config['dbname'] must be set\n");

  $defalib = preg_replace('/\n.*/', '', 
			  `sh -c 'locate adodb-session.php' 2>/dev/null`);
  if ($defalib) {
    $defalib = dirname($defalib);
    $defstr = "[$defalib] ";
  }

  $stdin = fopen('php://stdin', 'r');

  echo "Where is your adodb library located? " . $defstr;
  $alib = trim(fgets($stdin));
  if (!$alib) $alib = $defalib;
  echo "\n";

  if (!is_dir($alib)) die("Can't find adodb library directory\n");

  @symlink($alib, 'lib/adodb');

  $defpath = '/athena/';
  if (!($defhost = chop(`hostname`))) $defhost = 'example.com';
  $defurl = "http://$defhost$defpath";

  echo "What URL will your initial instance be located at?\n"
     . "[$defurl] ";

  $urlstr = trim(fgets($stdin));
  $url = parse_url($urlstr);

  if ($url['host']) {
    $domain = $url['host'];
    if ($path = $url['path']) {
      if (!(substr($path, -1) == '/')) $path .= '/';
    } else $path = '/';
  } else {
    $domain = $defhost;
    $path = $defpath;
    $url = $defurl;
  }

  echo "\n" .
       ">> Initial instance will have:\n" .
       ">>   Web domain: $domain\n" .
       ">>   Web path: $path\n" .
       ">>   Email address: default@$domain\n\n" .
       "[Press return to begin install or ^C to cancel]\n";

  fgets($stdin);

  require_once 'lib/db.php';
  require_once 'lib/crm.php';
  require_once 'lib/person.php';
  require_once 'lib/problem_type.php';
  require_once 'lib/source.php';

  $sql_files = array(
    'tables'  => array(
      'sessions.sql',
      'date_types.sql',
      'date_list.sql',
      'drop_downs.sql',
      'config.sql',
      'yes_no.sql',
      'modify_ticket_types.sql',
      'person_type.sql',
      'states.sql',
      'record_status.sql',
      'person.sql',
      'company.sql',
      'company_crm.sql',
      'crm_config.sql',
      'person_crm_map.sql',
      'person_crm_type_assign.sql',
      'problem_type.sql',
      'source.sql',
      'templates.sql',
      'ticket_status.sql',
      'ticket.sql',
      'ticket_crm_map.sql',
      'ticket_owner_transfer.sql',
      'comments.sql',
      'usernames.sql',
      'search_queries.sql',
      'search_result_queries.sql',
      'search_results.sql',
      'value_group.sql',
      'value_group_members.sql',
      'attribute_types.sql',
      'attribute.sql',
      'attribute_values.sql',
      'web_display_types.sql',
      'web_page.sql',
      'web_page_attributes_map.sql',
      'config_keys.sql',
      'email_ticket_map.sql',
      'crm_to_crm_access.sql',
      'bad_tickets.sql',
      'help.sql',
      'link_help_map.sql',
      'comment_attachments.sql',
      'blobtable.sql',
    ),
    'data'  => array(
      'date_types.sql',
      'date_list',
      'modify_ticket_types.sql',
      'ticket_status.sql',
      'record_status.sql',
      'yes_no.sql',
      'web_display_types.sql',
      'states.sql',
      'web_page',
      'company.sql',
      'company_crm',
      'person',
      'person_type.sql',
      'problem_type',
      'source',
      'person_crm_map',
      'person_crm_type_assign.sql',
      'attribute_types.sql',
      'drop_downs.sql',
      'help.sql',
      'link_help_map.sql'
    ),
    'indexes' => array(
      'attribute_values.sql',
      'config.sql',
      'drop_downs.sql',
      'person.sql',
      'ticket.sql',
      'ticket_crm_map.sql',
      'help.sql',
      'link_help_map.sql'
    )
  );

  echo 'Drop all tables currently in the selected db? [y/N] ';

  $yn = fgets($stdin);
  fclose($stdin);

  echo "\n";

  if (strchr(strtolower($yn), 'y')) {
    if ($driver == 'pgsql') {
      $sql = 
	"SELECT relname FROM pg_class WHERE relkind='%s' AND relname !~ '^pg_'";

      foreach (test_result($dbi->getCol(sprintf($sql, 'r'))) as $table) {
	if (!$t++) echo ">> Dropping all tables:\n";
	echo ">>   $table\n";
	test_result($dbi->query("DROP TABLE $table CASCADE"));
      }

      foreach (test_result($dbi->getCol(sprintf($sql, 'S'))) as $seq) {
	if (!$s++) echo ">> Dropping all sequences:\n";
	echo ">>   $seq\n";
	test_result($dbi->query("DROP SEQUENCE $seq"));
      }
    } elseif ($driver == 'mysql') {
      $t = 0;
      foreach (test_result($dbi->getCol('SHOW TABLES')) as $table) {
	if (!$t++) echo ">> Dropping all tables:\n";
	echo ">>   $table\n";
	test_result($dbi->query("DROP TABLE $table"));
      }
    } elseif ($driver == 'oci8') {
      foreach (test_result($dbi->getCol('select tname from tab')) as $table) {
	if (!$t++) echo ">> Dropping all tables:\n";
	echo ">>   $table\n";
	test_result($dbi->query("DROP TABLE $table CASCADE CONSTRAINTS"));
      }

      foreach (test_result($dbi->getCol(
	  'select sequence_name from user_sequences')) as $table) {
	if (!$t++) echo ">> Dropping all sequences:\n";
	echo ">>   $table\n";
	test_result($dbi->query("DROP SEQUENCE $table"));
      }
    }
  }

  foreach ($sql_files as $type => $files) {
    echo ">> Loading database $type:\n";
    foreach ($files as $file) load_sql($type, $file);
  }

  foreach (array('htdocs/.htaccess', 'tags') as $file) {
    echo ">> Creating $file from template\n";

    file_put($file,
      str_replace('__ATHENAROOT__', $athena_root, 
      str_replace('__DEFAULTINC__', ini_get('include_path'), 
    file_get("$file.in"))));
  }

  if (file_exists($custom_templates_dir)) {
    if (!is_dir($custom_templates_dir)) 
      echo ">> Custom templates directory '$custom_templates_dir' exists, but is not a directory!\n";
  } else {
    echo ">> Creating custom templates directory\n";
    mkdir($custom_templates_dir);
  }

  print <<<EOF
>> Done!

Installation is finished, now you need to configure your web and email services.

For web, make sure $urlstr 
points at $athena_root/htdocs
You can usually do this with a symlink or an entry in httpd.conf.

EOF;

  exit;

  function load_sql($type, $file) {
    global $dbi;
    global $driver;

    if (!preg_match('/\.sql$/', $file)) {
      echo ">>   Running: populate_$file()\n";
      return eval("populate_$file();");
    }

    if (file_exists("sql/$driver/$type/$file"))
      $file = "sql/$driver/$type/$file";
    elseif (file_exists("sql/shared/$type/$file"))
      $file = "sql/shared/$type/$file";
    else return;

    $f = fopen($file, 'r');
    $sql = fread($f, filesize($file));
    fclose($f);

    echo ">>   Loading: '$file'\n";

    if ($driver == 'mysql') {
      if ($type == 'tables') 
	$sql = preg_replace('/\btimestamp\b/i', 'datetime', $sql);
      load_split($sql);
    } elseif ($driver == 'oci8') {
      if ($type == 'tables') 
	$sql = preg_replace(
	  array('/\btimestamp\b/i', '/\btext\b/i'),
	  array('date', 	    'clob'),
	  $sql
	);
      load_split($sql);
    } else test_result($dbi->query($sql));
  }

  function load_split($sql) {
    global $dbi;

    $exprs = preg_grep('/^\s*--/',
      preg_grep('/\S/', preg_split('/;\s*\n/', $sql)), PREG_GREP_INVERT);

    if (count($exprs) > 1) {
      $n = 1;
      foreach ($exprs as $expr) {
	echo ">>     Loading expression $n\n"; $n++;
	test_result($dbi->query($expr));
      }
    } else test_result($dbi->query($exprs[0]));
  }

  function test_result($res) {
    if (DB::isError($res)) 
      die($res->getMessage() . "\n" . $res->getUserInfo() . "\n");
    return $res;
  }

  function file_get($file) {
    $f = fopen($file, 'r');
    $data = fread($f, filesize($file));
    fclose($f);
    return $data;
  }

  function file_put($file, $data) {
    $f = fopen($file, 'w');
    $n = fwrite($f, $data);
    fclose($f);
    return $n;
  }

  ## dynamic table population functions

  function populate_web_page() {
      global $dbi;

      $id = $dbi->nextId('web_page_id');
      $sql = "insert into web_page (web_page_id, created_by) values (?,?)";
      $res = $dbi->query($sql, array($id, 'default'));
      if (DB::isError($res))
	  die("Error populating table web_page: "
	    . $res->getMessage() . "\n" . $res->getUserInfo());
  }

  ## this should be CRM::Add()
  function populate_company_crm() {
      global $dbi;
      global $domain;
      global $path;

      $crm = new CRM();
      $id = $dbi->nextId('crm_id');

      $now = strftime('%Y-%m-%d %H:%M:%S');

      $add = array(
	      'crm_id' => $id,
	      'company_id' => 'DEFAULT',
	      'crm_name' => 'Default',
	      'crm_short_name' => 'default',
	      'web_page_id' => 1,
	      'created_by' => 'default',
	      'updated_by' => 'default',
	      'created_date' => $now,
	      'updated_date' => $now,
	      'email_domain' => $domain,
	      'web_domain' => $domain,
	      'web_path' => $path,
	      'users_url' => 'user/browse/',
	      'email_sig' => 'default',
	      'extended_email_sig' => 'default ext',
	      'default_support_person_id' => 1,
	      'default_escalated_to_id' => 1,
      );

      if (!$crm->Add($add))
	  die("Error populating table company_crm: ".$crm->error);
  }

  function populate_person() {
      $p = new Person();
      $pass = '5f4dcc3b5aa765d61d8327deb882cf99';

      $add = array(
	  'first_name' => 'default',
	  'last_name' => 'default',
      );
      $person_id = $p->Add($add);

      if (!$person_id) die("Error populating table person: ".$p->error);

      if (!$p->Update_Password($person_id, $pass))
	  die("Error setting default password: ".$p->error);
  }

  function populate_person_crm_map() {
      $p = new Person();
      $add = array(
	  'person_id' => 1,
	  'crm_id' => 1,
	  'current' => 'Y',
	  'support_drop_down' => 'Y',
	  'escalated_drop_down' => 'Y',
	  'modify_tickets' => 'Y',
      );

      if (!$p->Add_Map($add))
	die("Error populating table person_crm: ".$p->error);
  }

  function populate_problem_type () {
    $pt = new Problem_Type();

    $add = array(
      'crm_id' => 1,
      'problem_type' => 'default',
    );

    if (!$pt->Add($add))
      die("Error populating table problem_type: ".$pt->error);
  }

  function populate_source() {
    $s = new Source();

    $add = array(
      'crm_id' => 1,
      'source' => 'default',
    );

    if (!$s->Add($add))
      die("Error populating table source: ".$s-error);
  }

  function populate_date_list() {
    $dates = array(
      'YEAR' => array(
        '1990-01-01 00:00:00',
        '1991-01-01 00:00:00',
        '1992-01-01 00:00:00',
        '1993-01-01 00:00:00',
        '1994-01-01 00:00:00',
        '1995-01-01 00:00:00',
        '1996-01-01 00:00:00',
        '1997-01-01 00:00:00',
        '1998-01-01 00:00:00',
        '1999-01-01 00:00:00',
        '2000-01-01 00:00:00',
        '2001-01-01 00:00:00',
        '2002-01-01 00:00:00',
        '2003-01-01 00:00:00',
        '2004-01-01 00:00:00',
        '2005-01-01 00:00:00',
        '2006-01-01 00:00:00',
        '2007-01-01 00:00:00',
        '2008-01-01 00:00:00',
        '2009-01-01 00:00:00',
        '2010-01-01 00:00:00',
      ),
      'DAY' => array(
        '2002-01-01 00:00:00',
        '2002-01-02 00:00:00',
        '2002-01-03 00:00:00',
        '2002-01-04 00:00:00',
        '2002-01-05 00:00:00',
        '2002-01-06 00:00:00',
        '2002-01-07 00:00:00',
        '2002-01-08 00:00:00',
        '2002-01-09 00:00:00',
        '2002-01-10 00:00:00',
        '2002-01-11 00:00:00',
        '2002-01-12 00:00:00',
        '2002-01-13 00:00:00',
        '2002-01-14 00:00:00',
        '2002-01-15 00:00:00',
        '2002-01-16 00:00:00',
        '2002-01-17 00:00:00',
        '2002-01-18 00:00:00',
        '2002-01-19 00:00:00',
        '2002-01-20 00:00:00',
        '2002-01-21 00:00:00',
        '2002-01-22 00:00:00',
        '2002-01-23 00:00:00',
        '2002-01-24 00:00:00',
        '2002-01-25 00:00:00',
        '2002-01-26 00:00:00',
        '2002-01-27 00:00:00',
        '2002-01-28 00:00:00',
        '2002-01-29 00:00:00',
        '2002-01-30 00:00:00',
        '2002-01-31 00:00:00',
      ),
      'MON' => array(
        '2002-01-01 00:00:00',
        '2002-02-01 00:00:00',
        '2002-03-01 00:00:00',
        '2002-04-01 00:00:00',
        '2002-05-01 00:00:00',
        '2002-06-01 00:00:00',
        '2002-07-01 00:00:00',
        '2002-08-01 00:00:00',
        '2002-09-01 00:00:00',
        '2002-10-01 00:00:00',
        '2002-11-01 00:00:00',
        '2002-12-01 00:00:00',
      ),
    );

    $to_date = to_date();
if (!$to_date) die ("no to_date for date_list data\n");

    $sql = " insert into date_list (date_val,type) values ($to_date, ?) ";

    global $dbi;

    $h = $dbi->prepare( $sql );

    if (DB::isError($h))
       die('prepare date insert: '.$h->getMessage()."\n".$h->getUserInfo());

    foreach ($dates as $type => $type_list) {
      foreach ($type_list as $date) {
        $ok = $dbi->execute( $h, array($date,$type) );    

        if (DB::isError($ok))
           die("date insert: $sql\n$date => $type\n".$ok->getMessage()."\n".$ok->getUserInfo());
      }
    }
  }
?>
