package com.airlock.iam.base.misc.message;

import java.text.FieldPosition;
import java.text.Format;
import java.text.ParsePosition;
import org.apache.commons.lang3.StringUtils;

public class GrowableFormat extends Format {
   private static final String ABBREVIATION_STR = "..";
   private final int minSizeLeft;
   private final int minSizeRight;
   private int growBy;
   private boolean canGrow;

   public GrowableFormat(int minSizeLeft, int minSizeRight) {
      this.minSizeLeft = minSizeLeft < 1 ? 0 : minSizeLeft;
      this.minSizeRight = minSizeRight < 1 ? 0 : minSizeRight;
   }

   @Override
   public Object parseObject(String source, ParsePosition pos) throws UnsupportedOperationException {
      throw new UnsupportedOperationException("parseObject not supported");
   }

   public void growBy(int chars) {
      this.growBy += chars;
   }

   public boolean canGrow() {
      return this.canGrow;
   }

   @Override
   public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
      String input = obj == null ? null : obj.toString();
      return toAppendTo.append(this.abbreviate(input));
   }

   private String abbreviate(String str) {
      this.canGrow = true;
      if (str == null) {
         this.canGrow = false;
         return "null";
      }

      if (this.minSizeRight == 0) {
         if (str.length() <= this.minSizeLeft + "..".length() + this.growBy) {
            this.canGrow = false;
            return str;
         } else {
            return StringUtils.left(str, this.minSizeLeft + this.growBy) + "..";
         }
      } else if (this.minSizeLeft == 0) {
         if (str.length() <= this.minSizeRight + "..".length() + this.growBy) {
            this.canGrow = false;
            return str;
         } else {
            return ".." + StringUtils.right(str, this.minSizeRight + this.growBy);
         }
      } else if (str.length() <= this.minSizeRight + this.minSizeLeft + "..".length() + this.growBy) {
         this.canGrow = false;
         return str;
      } else {
         double half = this.growBy / 2.0;
         int leftGrowBy = (int)Math.ceil(half);
         int rightGrowBy = (int)Math.floor(half);
         return StringUtils.left(str, this.minSizeLeft + leftGrowBy) + ".." + StringUtils.right(str, this.minSizeRight + rightGrowBy);
      }
   }
}
