<%
  /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements. See the NOTICE file
  * distributed with this work for additional information
  * regarding copyright ownership. The ASF licenses this file
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License. You may obtain a copy of the License at
  *
  * http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ page import="java.util.*" %>
<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
<%@ page import="org.apache.tajo.master.*" %>
<%@ page import="org.apache.tajo.catalog.*" %>
<%@ page import="org.apache.tajo.util.FileUtil" %>
<%
  TajoMaster master = (TajoMaster) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
  CatalogService catalog = master.getCatalog();

  String selectedDatabase = request.getParameter("database");
  if(selectedDatabase == null || selectedDatabase.trim().isEmpty()) {
    selectedDatabase = "default";
  }

  TableDesc tableDesc = null;
  String selectedTable = request.getParameter("table");
  if(selectedTable != null && !selectedTable.trim().isEmpty()) {
    tableDesc = catalog.getTableDesc(selectedTable);
  } else {
    selectedTable = "";
  }

  //TODO filter with database
  Collection<String> tableNames = catalog.getAllTableNames();
%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <link rel="stylesheet" type = "text/css" href = "/static/style.css" />
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>Tajo</title>
</head>
<body>
<%@ include file="header.jsp"%>
<div class='contents'>
  <h2>Tajo Master: <%=master.getMasterName()%></h2>
  <hr/>
  <h3>Catalog</h3>
  <p/>
  <table width="100%" border='0'>
    <tr>
      <!-- left -->
      <td width="20%" valign="top">
        <div>
          <b>Database:</b>
          <select width="190" style="width: 190px">
            <option value="default" selected>default</option>
          </select>
        </div>
        <!-- table list -->
        <div style='margin-top:5px'>
<%
  if(tableNames == null || tableNames.isEmpty()) {
    out.write("No tables");
  } else {
%>
          <table width="100%" border="1" class="border_table">
            <tr><th>Table Name</th></tr>
<%
    for(String eachTableName: tableNames) {
      String bold = "";
      if(eachTableName.equals(selectedTable)) {
        bold = "font-weight:bold";
      }
      String detailLink = "catalogview.jsp?database=" + selectedDatabase + "&table=" + eachTableName;
      out.write("<tr><td><span style='" + bold + "'><a href='" + detailLink + "'>" + eachTableName + "</a></span></td></tr>");
    }
%>
          </table>
<%
  }
%>
        </div>
      </td>
      <!-- right -->
      <td width="80%" valign="top">
        <div style='margin-left: 15px'>
          <div style='font-weight:bold'>Table name: <%=selectedTable%></div>
          <div style='margin-top:5px'>
<%
    if(tableDesc != null) {
      List<Column> columns = tableDesc.getSchema().getColumns();
      out.write("<table border='1' class='border_table'><tr><th>No</th><th>Column name</th><th>Type</th></tr>");
      int columnIndex = 1;
      for(Column eachColumn: columns) {
        out.write("<tr><td width='30' align='right'>" + columnIndex + "</td><td width='320'>" + eachColumn.getColumnName() + "</td><td width='150'>" + eachColumn.getDataType().getType() + "</td></tr>");
        columnIndex++;
      }

      String optionStr = "";
      String prefix = "";
      for(Map.Entry<String, String> entry: tableDesc.getMeta().toMap().entrySet()) {
        optionStr += prefix + "'" + entry.getKey() + "'='" + entry.getValue() + "'";
        prefix = "<br/>";
      }
      out.write("</table>");
%>
          </div>
          <div style='margin-top:10px'>
            <div style=''>Detail</div>
            <table border="1" class='border_table'>
              <tr><td width='100'>Table path</td><td width='410'><%=tableDesc.getPath()%></td></tr>
              <tr><td>Store type</td><td><%=tableDesc.getMeta().getStoreType()%></td></tr>
              <tr><td># rows</td><td><%=tableDesc.getMeta().getStat().getNumRows()%></td></tr>
              <tr><td>Volume</td><td><%=FileUtil.humanReadableByteCount(tableDesc.getMeta().getStat().getNumBytes(),true)%></td></tr>
              <tr><td>Options</td><td><%=optionStr%></td></tr>
            </table>
          </div>
        </div>
<%
    }
%>
      </td>
    </tr>
  </table>
</div>
</body>
</html>
