/**
 * 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.
 */
package org.apache.hadoop.tools;

import java.util.ArrayList;
import java.util.LinkedList;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.apache.hadoop.classification.InterfaceAudience;

/**
 * This class implements a "table listing" with column headers.
 *
 * Example:
 *
 * NAME   OWNER   GROUP   MODE       WEIGHT
 * pool1  andrew  andrew  rwxr-xr-x     100
 * pool2  andrew  andrew  rwxr-xr-x     100
 * pool3  andrew  andrew  rwxr-xr-x     100
 *
 */
@InterfaceAudience.Private
public class TableListing {
  public enum Justification {
    LEFT,
    RIGHT;
  }

  private static class Column {
    private final ArrayList<String> rows;
    private final Justification justification;
    private final boolean wrap;

    private int wrapWidth = Integer.MAX_VALUE;
    private int maxWidth;

    Column(String title, Justification justification, boolean wrap) {
      this.rows = new ArrayList<String>();
      this.justification = justification;
      this.wrap = wrap;
      this.maxWidth = 0;
      addRow(title);
    }

    private void addRow(String val) {
      if (val == null) {
        val = "";
      }
      if ((val.length() + 1) > maxWidth) {
        maxWidth = val.length() + 1;
      }
      // Ceiling at wrapWidth, because it'll get wrapped
      if (maxWidth > wrapWidth) {
        maxWidth = wrapWidth;
      }
      rows.add(val);
    }

    private int getMaxWidth() {
      return maxWidth;
    }

    private void setWrapWidth(int width) {
      wrapWidth = width;
      // Ceiling the maxLength at wrapWidth
      if (maxWidth > wrapWidth) {
        maxWidth = wrapWidth;
      }
      // Else we need to traverse through and find the real maxWidth
      else {
        maxWidth = 0;
        for (int i=0; i<rows.size(); i++) {
          int length = rows.get(i).length();
          if (length > maxWidth) {
            maxWidth = length;
          }
        }
      }
    }

    /**
     * Return the ith row of the column as a set of wrapped strings, each at
     * most wrapWidth in length.
     */
    String[] getRow(int idx) {
      String raw = rows.get(idx);
      // Line-wrap if it's too long
      String[] lines = new String[] {raw};
      if (wrap) {
        lines = WordUtils.wrap(lines[0], wrapWidth, "\n", true).split("\n");
      }
      for (int i=0; i<lines.length; i++) {
        if (justification == Justification.LEFT) {
          lines[i] = StringUtils.rightPad(lines[i], maxWidth);
        } else if (justification == Justification.RIGHT) {
          lines[i] = StringUtils.leftPad(lines[i], maxWidth);
        }
      }
      return lines;
    }
  }

  public static class Builder {
    private final LinkedList<Column> columns = new LinkedList<Column>();
    private boolean showHeader = true;
    private int wrapWidth = Integer.MAX_VALUE;

    /**
     * Create a new Builder.
     */
    public Builder() {
    }

    public Builder addField(String title) {
      return addField(title, Justification.LEFT, false);
    }

    public Builder addField(String title, Justification justification) {
      return addField(title, justification, false);
    }

    public Builder addField(String title, boolean wrap) {
      return addField(title, Justification.LEFT, wrap);
    }

    /**
     * Add a new field to the Table under construction.
     *
     * @param title Field title.
     * @param justification Right or left justification. Defaults to left.
     * @param wrap Width at which to auto-wrap the content of the cell.
     *        Defaults to Integer.MAX_VALUE.
     * @return This Builder object
     */
    public Builder addField(String title, Justification justification,
        boolean wrap) {
      columns.add(new Column(title, justification, wrap));
      return this;
    }

    /**
     * Whether to hide column headers in table output
     */
    public Builder hideHeaders() {
      this.showHeader = false;
      return this;
    }

    /**
     * Whether to show column headers in table output. This is the default.
     */
    public Builder showHeaders() {
      this.showHeader = true;
      return this;
    }

    /**
     * Set the maximum width of a row in the TableListing. Must have one or
     * more wrappable fields for this to take effect.
     */
    public Builder wrapWidth(int width) {
      this.wrapWidth = width;
      return this;
    }

    /**
     * Create a new TableListing.
     */
    public TableListing build() {
      return new TableListing(columns.toArray(new Column[0]), showHeader,
          wrapWidth);
    }
  }

  private final Column columns[];

  private int numRows;
  private final boolean showHeader;
  private final int wrapWidth;

  TableListing(Column columns[], boolean showHeader, int wrapWidth) {
    this.columns = columns;
    this.numRows = 0;
    this.showHeader = showHeader;
    this.wrapWidth = wrapWidth;
  }

  /**
   * Add a new row.
   *
   * @param row    The row of objects to add-- one per column.
   */
  public void addRow(String... row) {
    if (row.length != columns.length) {
      throw new RuntimeException("trying to add a row with " + row.length +
            " columns, but we have " + columns.length + " columns.");
    }
    for (int i = 0; i < columns.length; i++) {
      columns[i].addRow(row[i]);
    }
    numRows++;
  }

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    // Calculate the widths of each column based on their maxWidths and
    // the wrapWidth for the entire table
    int width = (columns.length-1)*2; // inter-column padding
    for (int i=0; i<columns.length; i++) {
      width += columns[i].maxWidth;
    }
    // Decrease the column size of wrappable columns until the goal width
    // is reached, or we can't decrease anymore
    while (width > wrapWidth) {
      boolean modified = false;
      for (int i=0; i<columns.length; i++) {
        Column column = columns[i];
        if (column.wrap) {
          int maxWidth = column.getMaxWidth();
          if (maxWidth > 10) {
            column.setWrapWidth(maxWidth-1);
            modified = true;
            width -= 1;
            if (width <= wrapWidth) {
              break;
            }
          }
        }
      }
      if (!modified) {
        break;
      }
    }

    int startrow = 0;
    if (!showHeader) {
      startrow = 1;
    }
    String[][] columnLines = new String[columns.length][];
    for (int i = startrow; i < numRows + 1; i++) {
      int maxColumnLines = 0;
      for (int j = 0; j < columns.length; j++) {
        columnLines[j] = columns[j].getRow(i);
        if (columnLines[j].length > maxColumnLines) {
          maxColumnLines = columnLines[j].length;
        }
      }

      for (int c = 0; c < maxColumnLines; c++) {
        // First column gets no left-padding
        String prefix = "";
        for (int j = 0; j < columns.length; j++) {
          // Prepend padding
          builder.append(prefix);
          prefix = " ";
          if (columnLines[j].length > c) {
            builder.append(columnLines[j][c]);
          } else {
            builder.append(StringUtils.repeat(" ", columns[j].maxWidth));
          }
        }
        builder.append("\n");
      }
    }
    return builder.toString();
  }
}
