<?php
require_once("config.php");

class write {
  public static function do($json) {
    echo json_encode($json)."\n";
    exit();
  }
}

class conv {
  public static function ask($msg_array) {
    $items = array();

    foreach ($msg_array as $msg) {
      $items[] = array("simpleResponse" => array("textToSpeech" => $msg));
    }

    self::ask_custom($items);
  }

  public static function ask_followup($msg, &$i18n) {
    self::ask([$msg, $i18n->msg("followup_".mt_rand(1, 3))]);
  }

  public static function ask_custom($items) {
    $json = array();
    $json["payload"] = array();
    $json["payload"]["google"] = array();
    $json["payload"]["google"]["expectUserResponse"] = true;
    $json["payload"]["google"]["richResponse"] = array();
    $json["payload"]["google"]["richResponse"]["items"] = $items;

    write::do($json);
  }

  public static function has($item, &$json) {
    foreach ($json["originalDetectIntentRequest"]["payload"]["surface"]["capabilities"] as $cap) {
      if ($cap["name"] == $item) {
        return true;
      }
    }
    return false;
  }
}

class i18n {
  public static $hllist = array("en", "es");
  public $i18n_strings = null;
  public $language = null;

  function __construct($lang) {
    global $_GET;
    global $conf;

    if (empty($this->i18n_strings)) {
      $this->i18n_strings = array();
    }

    $this->language = $lang;

    $this->i18n_strings = json_decode(file_get_contents("assistant/".$this->language.".json"), true);

    return true;
  }

  function msg($message, $strings = null) {
    if (!isset($this->i18n_strings[$message])) {
      return false;
    }

    $string = $this->i18n_strings[$message];

    if ($strings != null && is_array($strings)) {
      foreach ($strings as $i => $subst) {
        $string = str_replace("{".$i."}", $subst, $string);
      }
    }

    return $string;
  }
}

function get_graph() {
  global $conf;
  return json_decode(file_get_contents($conf["apiurl"]), true);
}

function comma($array, $wait=false) {
  global $i18n;
  if (count($array) == 0) {
    return "";
  }
  if (count($array) == 1) {
    return $array[0];
  }
  $break = ($wait ? '<break time="0.5s"/>' : "");
  return implode($break.", ", array_slice($array, 0, -1)).$break.", ".$i18n->msg("and")." ".$array[count($array)-1];
}

$json = json_decode(file_get_contents('php://input'), true);

if ($json === NULL || !isset($json["originalDetectIntentRequest"]) || !isset($json["originalDetectIntentRequest"]["source"]) || $json["originalDetectIntentRequest"]["source"] != "google") {
  exit();
}

$graph = get_graph();
$lang = (isset($json["queryResult"]["languageCode"]) && in_array(substr($json["queryResult"]["languageCode"], 0, 2), i18n::$hllist) ? substr($json["queryResult"]["languageCode"], 0, 2) : "en");
$i18n = new i18n($lang);

switch ($json["queryResult"]["intent"]["displayName"]) {
  case "showVertex":
  if (!isset($json["queryResult"]["parameters"]["Vertex"])) {
    exit();
  }
  
  $shortest = -1;
  $closest = -1;
  $closest_id = -1;

  foreach ($graph["nodes"] as $id => $node) {
    $lev = levenshtein(strtolower($json["queryResult"]["parameters"]["Vertex"]), strtolower($node["name"]));

    if ($lev == 0) {
      $closest = $node["name"];
      $shortest = $lev;
      $closest_id = $id;
    }

    if (($lev <= $shortest || $shortest < 0) && $lev <= 3) {
      $closest = $node["name"];
      $shortest = $lev;
      $closest_id = $id;
    }
  }

  if ($shortest != -1) {
    $neighbors = array();
    // We're suposing each vertex has a different name. If not, this would get rid of some of the edges, but if two vertexs had the same name there would be no way to differentiate them anyway, so I think it's ok.
    foreach ($graph["edges"] as $edge) {
      if ($edge["a"] == $closest_id) {
        $neighbors[$graph["nodes"][$edge["b"]]["name"]] = $edge["votes"];
      } elseif ($edge["b"] == $closest_id) {
        $neighbors[$graph["nodes"][$edge["a"]]["name"]] = $edge["votes"];
      }
    }
    if (count($neighbors) == 0) {
      conv::ask_followup($i18n->msg("new_to_graph", array("person" => $closest)), $i18n);
    } else {
      arsort($neighbors);
      $params = array("person" => $closest, "count" => (count($neighbors) == 1 ? $i18n->msg("count_singular") : $i18n->msg("count_plural", array("count" => count($neighbors)))));
      /*if (conv::has("actions.capability.SCREEN_OUTPUT", $json)) {
        $items = [
          array(
            "simpleResponse" => array(
              "textToSpeech" => $i18n->msg("edges_display", $params)
            )
          ),
          array(
            "tableCard" => array(
              "columnProperties" => [
                array(
                  "header" => "Adjacent vertex"
                ),
                array("header" => "Votes")
              ],
              "rows" => []
            )
          ),
          array(
            "simpleResponse" => array(
              "textToSpeech" => $i18n->msg("followup_".mt_rand(1, 3))
            )
          )
        ];
        foreach ($neighbors as $neighbor => $votes) {
          $items[1]["tableCard"]["rows"][] = array("cells" => [array("text" => $neighbor), array("text" => (string)$votes)]);
        }
        conv::ask_custom($items);
      } else {*/ // This code shows a table if the user has a screen, but
                 // unfortunately tables are not public yet.
                 // @TODO: Uncomment when tables are out of developer preview.
        $people = array_keys($neighbors);
        $people_string = comma($people);
        $params["edges"] = $people_string;
        $num = mt_rand(1, 3);
        conv::ask_followup($i18n->msg("edges_".$num, $params), $i18n);
      /*}*/
    }
  } else {
    conv::ask_followup($i18n->msg("not_found", array("person" => $json["queryResult"]["parameters"]["Vertex"])), $i18n);
  }
  break;

  case "randomFact":
  $rand = mt_rand(0, 5);
  switch ($rand) {
    case 0: // Last edge in the graph
    $last = array_values(array_slice($graph["edges"], -1))[0];
    conv::ask_followup($i18n->msg("random_fact", array("fact" => $i18n->msg("didyouknow_last_edge", array("person1" => $graph["nodes"][$last["a"]]["name"], "person2" => $graph["nodes"][$last["b"]]["name"])))), $i18n);
    break;

    case 1: // Num vertices
    conv::ask_followup($i18n->msg("didyouknow_num_vertices", array("count" => count($graph["nodes"]))), $i18n);
    break;

    case 2: // Num edges
    conv::ask_followup($i18n->msg("didyouknow_num_edges", array("count" => count($graph["edges"]))), $i18n);
    break;

    case 3: // First 3 vertices K3
    conv::ask_followup($i18n->msg("random_fact", array("fact" => $i18n->msg("didyouknow_k3"))), $i18n);
    break;

    case 4: // Creator
    conv::ask_followup($i18n->msg("didyouknow_creator"), $i18n);
    break;

    case 5: // Groph
    conv::ask_followup($i18n->msg("random_fact", array("fact" => $i18n->msg("didyouknow_groph"))), $i18n);
    break;
  }
  
  break;

  case "numVertexs":
  conv::ask_followup($i18n->msg("num_vertices", array("count" => count($graph["nodes"]))), $i18n);
  break;

  case "numEdges":
  conv::ask_followup($i18n->msg("num_edges", array("count" => count($graph["edges"]))), $i18n);
  break;

  case "latestNews":
  $param = (isset($json["queryResult"]["parameters"]["numEdges"]) ? $json["queryResult"]["parameters"]["numEdges"] : null);
  $num = (isset($param) && !empty($param) ? (int)$param : 4);
  $last = array_values(array_slice($graph["edges"], -$num));
  $edges = [];
  foreach ($last as $edge) {
    $edges[] = $graph["nodes"][$edge["a"]]["name"]." - ".$graph["nodes"][$edge["b"]]["name"];
  }
  $edges_string = comma($edges, true);
  conv::ask_followup($i18n->msg((isset($param) && !empty($param) ? "latest_news_count" : "latest_news"), array("edges" => $edges_string, "count" => $num)), $i18n);
  break;

  default:
  exit();
}
