<?php

class Condition extends Zend_Db_Table_Abstract {
  protected $_name = 'necosuke_lpo_mast_condition';
  protected $_rowClass = 'ConditionRow';
  protected $_dependentTables = array('Content', 'Log');
  protected $_referenceMap = array(
    'Lpo' => array(
      'columns'       => 'lpo_id',
      'refTableClass' => 'Lpo',
      'refColumns'    => 'id',
      #'onDelete'      => self::CASCADE,
    ),
  );

  public function insert($data) {
    $data['priority'] = new Zend_Db_Expr('unix_timestamp()');
    $data['created']  = new Zend_Db_Expr('now()');
    $data['updated']  = new Zend_Db_Expr('now()');

    return parent::insert($data);
  }

  public function update($data, $where) {
    $data['updated']  = new Zend_Db_Expr('now()');

    return parent::update($data, $where);
  }
}

class ConditionRow extends Zend_Db_Table_Row_Abstract {
  public function parseQuery($query) {
    $ret = array();

    foreach(explode('&', $query) as $val) {
      list($key, $v) = explode('=', $val);
      $ret[$key] = mb_convert_encoding(urldecode($v), 'UTF-8', 'AUTO');
    }

    return $ret;
  }

  public function parseKeyword($ref) {
    $s = array();
    $s['ww.google.co.jp'][] = 'q';
    $s['www.google.co.jp'][] = 'q';
    $s['www.google.co.jp'][] = 'as_q';
    $s['www.google.com'][] = 'q';
    $s['www.google.com'][] = 'as_q';
    $s['www.google.com.au'][] = 'q';
    $s['search.yahoo.co.jp'][] = 'p';
    $s['search.yahoo.co.jp'][] = 'va';
    $s['search.yahoo.com'][] = 'p';
    $s['websearch.yahoo.co.jp'][] = 'p';
    $s['search.live.com'][] = 'q';
    $s['msn.com'][] = 'qt';
    $s['search.msn.com'][] = 'q';
    $s['search.msn.co.jp'][] = 'q';
    $s['jp.search.msn.com'][] = 'q';
    $s['ie.search.msn.com'][] = 'q';
    $s['sea.search.msn.co.jp'][] = 'q';
    $s['msn.com.br'][] = 'q';
    $s['search.msn.com.br'][] = 'q';
    $s['www.excite.co.jp'][] = 'search';
    $s['apple.excite.co.jp'][] = 'search';
    $s['dion.excite.co.jp'][] = 'search';
    $s['home.excite.co.jp'][] = 'search';
    $s['hi-ho.excite.co.jp'][] = 'search';
    $s['odn.excite.co.jp'][] = 'search';
    $s['cybozu.excite.co.jp'][] = 'search';
    $s['duogate.excite.co.jp'][] = 'search';
    $s['so-net.excite.co.jp'][] = 'prev';
    $s['search.goo.ne.jp'][] = 'MT';
    $s['partners.search.goo.ne.jp'][] = 'MT';
    $s['ocnsearch.goo.ne.jp'][] = 'MT';
    $s['so-net.search.goo.ne.jp'][] = 'MT';
    $s['www.fresheye.com'][] = 'kw';
    $s['search.fresheye.com'][] = 'kw';
    $s['search.nifty.com'][] = 'Text';
    $s['azby.search.nifty.com'][] = 'Text';
    $s['www.infoseek.co.jp'][] = 'qt';
    $s['search.www.infoseek.co.jp'][] = 'qt';
    $s['cgi.search.biglobe.ne.jp'][] = 'q';
    $s['jword.search.biglobe.ne.jp'][] = 'q';
    $s['home.search.biglobe.ne.jp'][] = 'q';
    $s['search.livedoor.com'][] = 'q';
    $s['search.jp.aol.com'][] = 'query';
    $s['aolsearch.jp.aol.com'][] = 'query_contain';
    $s['aolsearch.jp.aol.com'][] = 'query';
    $s['9199.jword.jp'][] = 'name';
    $s['search.jword.jp'][] = 'name';
    $s['point.ecnavi.jp'][] = 'Keywords';
    $s['ask.jp'][] = 'q';
    $s['www.alltheweb.com'][] = 'q';
    $s['www.altavista.com'][] = 'q';
    $s['search.lifemile.jp'][] = 'Keywords';
    $s['s.luna.tv'][] = 'q';
    $s['ysearch.lunascape.jp'][] = 'p';

    $_ref = parse_url($ref);

    if(array_key_exists('host', $_ref) && array_key_exists($_ref['host'], $s)) {
      $qs = $s[$_ref['host']];

      if(!empty($qs)) {
        $query = $this->parseQuery($_ref['query']);

        foreach($qs as $val) {
          $ret = $query[$val];
          if(!empty($ret)) {
            return $ret;
          }
        }
      }
    }

    return null;
  }

  public function getRatedContent() {
    $content_t = new Content();

    $contents = $this->findDependentRowset(
      'Content',
      null,
      $content_t->select()->where('status = ?', 'active')->order('id')
    );

    $m = 0;
    foreach($contents as $content) {
      $m += $content->rate;
    }
    $n = round(rand(1, $m));

    $max = 0;
    foreach($contents as $content) {
      $min  = $max;
      $max += $content->rate;
      if($min < $n && $n <= $max) {
        return $content;
      }
    }

    return null;
  }

  public function getContent($url, $ref) {
    switch($this->condition) {
      case 'all':
        break;
      case 'keyword':
        if(preg_match("/{$this->value}/i", $this->parseKeyword($ref)) == 0) {
          return null;
        }
        break;
      case 'referrer':
        if(strncmp($this->value, $ref, strlen($this->value)) != 0) {
          return null;
        }
        break;
      case 'query':
        $_url = parse_url($url);
        $query = explode('&', $_url['query']);
        if(!array_key_exists($this->value, $query)) {
          return null;
        }
        break;
    }

    if($content = $this->getRatedContent()) {
      return array($this, $content);
    } else {
      return array();
    }
  }

  public function priorityUp() {
    $condition_t = new Condition();
    
    $prev = $condition_t->fetchRow(
      $condition_t->select()
        ->where('lpo_id = ?', $this->lpo_id)
        ->where('priority < ?', $this->priority)
        ->order('priority DESC')
        ->limit(1)
    );

    if(!$prev) {
      return;
    }

    $a = $this->priority;
    $this->priority = $prev->priority;
    $prev->priority = $a;

    $this->save();
    $prev->save();
  }

  public function priorityDown() {
    $condition_t = new Condition();
    
    $next = $condition_t->fetchRow(
      $condition_t->select()
        ->where('lpo_id = ?', $this->lpo_id)
        ->where('priority > ?', $this->priority)
        ->order('priority')
        ->limit(1)
    );

    if(!$next) {
      return;
    }

    $a = $this->priority;
    $this->priority = $next->priority;
    $next->priority = $a;

    $this->save();
    $next->save();
  }

  public function del() {
    $this->status = 'deleted';

    foreach($this->findDependentRowset('Content', null) as $content) {
      $content->del();
      $content->save();
    }
  }

  public function getName() {
    switch($this->condition) {
      case 'all':
        return '必ず表示する';
      case 'keyword':
        return 'キーワード: ' . $this->value;
      case 'referrer':
        return 'リファラー: ' . $this->value;
      case 'query':
        return'パラメータ: ' . $this->value;
      default:
        return null;
    }
  }
}
