/*
 * 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.geode.management.internal.cli.result;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.geode.management.internal.cli.shell.Gfsh;

/**
 * Helps table builder for adjusting result width according to screen width
 *
 */

public class TableBuilderHelper {

  private static final int SCREEN_WIDTH_MARGIN_BUFFER = 5;

  public static class Column implements Comparable<Column> {
    int length;
    int originalIndex;
    boolean markForTrim = false;
    int trimmedLength = 0;

    @Override
    public int compareTo(Column o) {
      return length - o.length;
    }

    public String toString() {
      return ("OI:" + originalIndex + "<" + length + ">\n");
    }

  }

  public static class TooManyColumnsException extends RuntimeException {
    public TooManyColumnsException(String str) {
      super(str);
    }
  }

  public static int[] recalculateColSizesForScreen(int screenWidth, int[] colSizes,
      String colSeparators) {

    if (shouldTrimColumns()) {
      int totalLength = 0;
      // change the screen width to account for separator chars
      screenWidth -= (colSizes.length - 1) * colSeparators.length();

      // build sorted list and find total width
      List<Column> stringList = new ArrayList<Column>();
      int index = 0;
      for (int k : colSizes) {
        Column cs = new Column();
        cs.originalIndex = index++;
        cs.length = k;
        stringList.add(cs);
        totalLength += k;
      }

      // No need to reduce the column width return orig array
      if (totalLength <= screenWidth) {
        return colSizes;
      }

      Collections.sort(stringList);

      // find out columns which need trimming
      totalLength = 0;
      int spaceLeft = 0;
      int totalExtra = 0;
      for (Column s : stringList) {
        int newLength = totalLength + s.length;
        // Ensure that the spaceLeft is never < 2 which would prevent displaying a trimmed value
        // even when there is space available on the screen.
        if (newLength + SCREEN_WIDTH_MARGIN_BUFFER > screenWidth) {
          s.markForTrim = true;
          totalExtra += s.length;
          if (spaceLeft == 0) {
            spaceLeft = screenWidth - totalLength;
          }
        }
        totalLength = newLength;
      }

      Collections.sort(stringList, (o1, o2) -> o1.originalIndex - o2.originalIndex);

      // calculate trimmed width for columns marked for
      // distribute the trimming as per percentage
      int finalColSizes[] = new int[colSizes.length];
      int i = 0;
      for (Column s : stringList) {
        if (totalLength > screenWidth) {
          if (s.markForTrim) {
            s.trimmedLength = (int) Math.floor((spaceLeft * ((double) s.length / totalExtra)));
            finalColSizes[i] = s.trimmedLength;
          } else {
            s.trimmedLength = s.length;
            finalColSizes[i] = s.trimmedLength;
          }
        } else {
          s.trimmedLength = s.length;
          finalColSizes[i] = s.trimmedLength;
        }
        i++;
      }

      totalLength = 0;
      index = 0;
      for (int colSize : finalColSizes) {
        if (colSize != colSizes[index] && colSize < 2)
          throw new TooManyColumnsException("Computed ColSize=" + colSize
              + " Set RESULT_VIEWER to external. This uses the 'less' command (with horizontal scrolling) to see wider results");
        totalLength += colSize;
        index++;
      }

      return finalColSizes;
    } else {
      // Returning original colSizes since reader is set to external
      return colSizes;
    }
  }

  public static int trimWidthForScreen(int maxColLength) {
    if (shouldTrimColumns()) {
      int screenWidth = getScreenWidth();
      if (maxColLength > screenWidth)
        return screenWidth;
      else
        return maxColLength;
    } else
      return maxColLength;

  }

  public static int getScreenWidth() {
    Gfsh gfsh = Gfsh.getCurrentInstance();
    if (gfsh == null)
      return Gfsh.DEFAULT_WIDTH;
    else
      return gfsh.getTerminalWidth();
  }

  public static boolean shouldTrimColumns() {
    Gfsh gfsh = Gfsh.getCurrentInstance();
    if (gfsh == null)
      return Boolean.getBoolean("GFSH.TRIMSCRWIDTH");
    else {
      return Gfsh.DEFAULT_APP_RESULT_VIEWER.equals(gfsh.getEnvProperty(Gfsh.ENV_APP_RESULT_VIEWER))
          && !Gfsh.isInfoResult();
    }

  }


}
