<?php

require_once "WEB-INF/php/inc.php";

if (! admin_init()) {
  return;
}

echo "<div id='health-tabs'>\n";
echo "<ul>";
echo "<li><a href='#health'>Health</a></li>\n";
echo "<li><a href='#health-graph'>Graphs</a></li>\n";
echo "<li><a href='#heartbeat'>Heartbeat</a></li>\n";
echo "<li><a href='#health-logs'>Health Logs</a></li>\n";
echo "</ul>";

echo "<div id='health'>\n";
display_health_tab();
echo "</div>\n";

echo "<div id='health-graph'>\n";
display_health_graph_tab();
echo "</div>\n";

echo "<div id='heartbeat'>\n";
display_heartbeat();
echo "</div>\n";

echo "<div id='health-logs'>\n";
display_health_logs();
echo "</div>\n";

echo "</div>\n";

function display_health_tab()
{
  global $g_server;

  echo "<h1>Cluster Health"; print_help("Health"); echo "</h1>\n";

  foreach ($g_server->SelfServer->Cluster->Servers as $s) {
    display_health_status($s);
  }
}

function display_health_graph_tab()
{
  global $g_server;

  echo "<h1>Cluster Health</h1>\n";

  foreach ($g_server->SelfServer->Cluster->Servers as $s) {
    display_health_status_graph($s);
  }
}

function display_health_status($s)
{
  $si = sprintf("%02d", $s->ClusterIndex);
  $server_id = $s->Name;

  $mbean_server = new MBeanServer($server_id);

  if ($mbean_server) {
    $health = $mbean_server->lookup("resin:type=HealthCheck,name=Resin");
  }
      
  $is_health = $health;

  $message = $health->Status;

  echo "<table border='0'>";
  echo "<tr><th colspan='3'>";

  echo "</th></tr>";

  echo "<tr><td>";

  echo "<span id='sw_health_status_${si}' class='switch'></span>";

  echo "</td><td>";

  $label = $si . " - " . $s->Name;

  if (! $health) {
    print_fail($label);
    $message = " : cannot connect to server $label";
  }
  else {
    print_health($health->Status, $label);
  }

  echo "</td><td>";

  echo $message;

  echo "</td></tr>";

  if ($mbean_server && $health) {
    $health_list = $mbean_server->query("resin:type=HealthCheck,*");
    foreach ($health_list as $s_health) {
      echo "<tr class='toggle-sw_health_status_${si}'>";
      echo "<td>";
      echo "</td>";
      echo "<td>";

      print_health($s_health->Status, $s_health->Name);

      echo "</td>";
      echo "<td>";
      echo $s_health->Message;
      echo "</td>";
      echo "</tr>";
    }
  }
  
  echo "</table>";
}

function display_health_status_graph($s)
{
  $si = sprintf("%02d", $s->ClusterIndex);
  $server_id = $s->Name;

  $mbean_server = new MBeanServer($server_id);

  if ($mbean_server) {
    $health = $mbean_server->lookup("resin:type=HealthCheck,name=Resin");
  }
      
  $is_health = $health;

  echo "<table border='0'>";
  echo "<tr><th colspan='3'>";

  echo "</th></tr>";

  echo "<tr><td>";

  echo "<span id='sw_health_${si}' class='switch'></span>";

  echo "</td><td>";

  $label = $si . " - " . $s->Name;

  if (! $health) {
    echo "n/a " . $label;
  }
  else {
  	print_health($health->Status, $label);
  }

  echo "</td><td>";

  echo $health->Status;

  echo "</td></tr>";

  echo "<tr class='toggle-sw_health_${si}'>";
  echo "<td colspan='3' id='health_${si}-legend'>";
  echo "</td>";
  echo "</tr>";
  
  echo "</table>";

  display_health_graph($mbean_server, $si);
}

function display_health_graph($mbean_server, $si)
{
  global $g_mbean_server;

  $stat_service = $mbean_server->lookup("resin:type=StatService");
  if ($stat_service) {
    $period = 24 * 60 * 60;
    $end = time();
    $start = $end - $period;

    $height = 100;
    $width = 500;
    
    $health_system = $mbean_server->lookup("resin:type=HealthSystem");
    if ($health_system) {
			$status_names = $health_system->HealthStatusNames;
    }
    
    stat_graph_regexp("health_${si}", $width, $height, $start, $end,
                      "/^$si\|Resin\|Health/", "none", $mbean_server, $status_names);
  }
}

function display_heartbeat()
{
  global $g_server;

  echo "<h1>Cluster Heartbeat"; print_help("Heartbeat"); echo "</h1>\n";

  $resin = $g_server->Cluster->Resin;
  $clusters = $resin->Clusters;

  echo "<table cellspacing='5'>";

  echo "<tr>";

  foreach ($clusters as $c) {
    echo "<th>" . $c->Name . "</th>\n"
  }

  echo "</tr>";

  for ($i = 0; $i < 64; $i++) {
    if (! has_server($clusters, $i))
      continue;

    echo "<tr>";

    foreach ($clusters as $c) {
      echo "<td>";
    
      $triad_a = $c->Servers[0];
      if ($triad_a) {
        $mbean_server_a = new MBeanServer($triad_a->Name);
      }
    
      $triad_b = $c->Servers[1];
      if ($triad_b) {
        $mbean_server_b = new MBeanServer($triad_b->Name);
      }

      $triad_c = $c->Servers[2];
      if ($triad_c) {    
        $mbean_server_c = new MBeanServer($triad_c->Name);
      }

      $s = $c->Servers[$i];

      if ($s) {
        $style = "border-width : 1px";

        $s_mbean_server = new MBeanServer($s->Name);
        $s_server = $s_mbean_server->lookup("resin:type=Server");

        if (! $s_server) {
          $style .= "; border-color : #cc0000";
        }
        else if ($s->Name === $g_server->SelfServer->Name) {
          $style .= "; border-color : #e5a122";
        }
      
        if ($s->isTriadServer()) {
          $style .= "; border-style : solid";
        }
        else {
          $style .= "; border-style : dashed";
        }

        echo "<table style='$style' width='100%'>\n";

        echo "<tr>";
        echo "<td>"
      
        $is_health = $s_server;
      
        print_check_or_x($is_health);
      
        echo "</td>"
        echo "<td width='5em'>";
  
      $name = $s->Name;
      if (! $name)
        $name = "default";
      printf("%02d - %s", $s->ClusterIndex, $name);

      echo "</td>\n";
      echo "<td>";

      do_triad($s, $triad_a, $mbean_server_a);

      echo "</td></tr>\n";
      echo "<tr><td>&nbsp;</td><td>";

      printf("%s:%d", $s->Address, $s->Port);

      echo "</td>\n<td>";

      do_triad($s, $triad_b, $mbean_server_b);

      echo "</td></tr>\n";

      //
      // third row - health and triad C
      // 

      $s_mbean_server = new MBeanServer($s->Name);
      $s_server = $s_mbean_server->lookup("resin:type=Server");
      $s_health = $s_mbean_server->lookup("resin:type=HealthCheck,name=Resin");
      
      $is_health = $s_server;
      
      echo "<tr><td>";
      if ($s_health) {
        echo "<span id='sw_${server}' class='switch'></span>";
      }
      echo "</td><td nowrap>";

      if (! $s_health) {
        echo "n/a";
      }
      else {
      	print_health($s_health->Status, "Health " . $s_health->Status);
      }
      
      echo "</td>";

      echo "<td>";

      do_triad($s, $triad_c, $mbean_server_c);
      
      echo "</td>";
      
      echo "</tr>\n";

      echo "<tr class='toggle-sw_${server}'>";
      echo "<td colspan='3'>";
      if ($s_server) {
        echo "<table border='0' style='border-width:1px'>\n";
        $s_health_list = $s_mbean_server->query("resin:type=HealthCheck,*");
        foreach ($s_health_list as $s_health) {
          $name = $s_health->Name;
          $msg = $s_health->Message;

          echo "<tr><td>";
          
          print_health($s_health->Status, $s_health->Name);
          
          echo "</td>";
          echo "<td>";
          echo $msg;
          echo "</td>";
          echo "</tr>";
        }
        echo "</table>";
      }
      echo "</td></tr>";
      echo "</table>\n";
    }

    echo "</td>";
  }

  echo "</tr>";
  }

  echo "</table>";
}

function has_server($clusters, $i)
{
  return true;
}  

function do_triad($s, $triad, $triad_mbean_server)
{
  if (! $triad) {
    echo "&nbsp;&nbsp;\n";
    return;
  }

  echo "<span style='font-size=1.2em'>";
  
  $s_mbean_server = new MBeanServer($s->Name);
  $s_server = $s_mbean_server->lookup("resin:type=Server");
  $s_triad_server = $s_server->SelfServer->Cluster->Servers[$triad->ClusterIndex];

  $triad_server = $triad_mbean_server->lookup("resin:type=Server");
  $triad_cluster = $triad_server->SelfServer->Cluster;
  $triad_cluster_server = $triad_cluster->Servers[$s->ClusterIndex];

  if (! $s_triad_server) {
    echo "<span>&ndash;</span>";
  }
  else if ($s_triad_server->isHeartbeatActive()) {
    echo "<span style='color:#00c000'>&larr;</span>";
  }
  else {
    echo "<span style='color:#c00000'>&#x2717;</span>";
  }

  if (! $triad_cluster_server) {
    echo "<span>&ndash;</span>";
  }
  else if ($triad_cluster_server->isHeartbeatActive()) {
    echo "<span style='color:#00c000'>&rarr;</span>";
  }
  else {
    echo "<span style='color:#c00000'>&#x2717;</span>";
  }
}

function display_health_logs()
{
  global $mbean_server;
  global $g_mbean_server;


  echo "<h1>Health Logs"; print_help("Health#Logs"); echo "</h1>\n";

  if ($g_mbean_server) {
    $mbean = $g_mbean_server->lookup("resin:type=LogService");
  }

  //
  // recent messages
  //

  if ($mbean) {
    $now = time();

    $messages = $mbean->findMessagesByName("com.caucho.env.health",
                                           "warning",
                                           ($now - 24 * 3600) * 1000,
                                           $now * 1000);
    if (! empty($messages)) {
      echo "<h1>Health Logs</h1>\n";

      echo "<table class='data'>\n";
  /*
      //echo "<thead class='scroll'>\n";
      echo "<tr><th class='date'>Date</th>"
      echo "    <th class='level'>Level</th>"
      echo "    <th class='message'>Message</th></tr>\n";
      //echo "</thead>\n";
  */

      $messages = array_reverse($messages);

      echo "<tbody class='scroll'>\n";
      foreach ($messages as $message) {
        echo "<tr class='{$message->level}'>";
        echo "  <td class='level'>{$message->level}</td>";
        echo "  <td class='date'>";
        echo strftime("%Y-%m-%d&nbsp;%H:%M:%S", $message->timestamp / 1000);
        echo "</td>";
        echo "  <td class='message'>" . htmlspecialchars(wordwrap($message->message, 90));
        echo "  </td>";
        echo "</tr>";
      }

      echo "</tbody>\n";
      echo "</table>\n";
    }
  }
}

display_footer($g_page, $javascript . javascript_create_tab("health-tabs"));

?>
