package org.apache.lucene.facet.taxonomy.writercache;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/*
 * 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.
 */

/**
 * Similar to {@link StringBuilder}, but with a more efficient growing strategy.
 * This class uses char array blocks to grow.
 * 
 * @lucene.experimental
 */
class CharBlockArray implements Appendable, Serializable, CharSequence {

  private static final long serialVersionUID = 1L;

  private final static int DefaultBlockSize = 32 * 1024;  // 32 KB default size

  final static class Block implements Serializable, Cloneable {
    private static final long serialVersionUID = 1L;

    final char[] chars;
    int length;

    Block(int size) {
      this.chars = new char[size];
      this.length = 0;
    }
  }

  List<Block> blocks;
  Block current;
  int blockSize;
  int length;

  CharBlockArray() {
    this(DefaultBlockSize);
  }

  CharBlockArray(int blockSize) {
    this.blocks = new ArrayList<Block>();
    this.blockSize = blockSize;
    addBlock();
  }

  private void addBlock() {
    this.current = new Block(this.blockSize);
    this.blocks.add(this.current);
  }

  int blockIndex(int index) {
    return index / blockSize;
  }

  int indexInBlock(int index) {
    return index % blockSize;
  }

  @Override
  public CharBlockArray append(CharSequence chars) {
    return append(chars, 0, chars.length());
  }

  @Override
  public CharBlockArray append(char c) {
    if (this.current.length == this.blockSize) {
      addBlock();
    }
    this.current.chars[this.current.length++] = c;
    this.length++;

    return this;
  }

  @Override
  public CharBlockArray append(CharSequence chars, int start, int length) {
    int end = start + length;
    for (int i = start; i < end; i++) {
      append(chars.charAt(i));
    }
    return this;
  }

  public CharBlockArray append(char[] chars, int start, int length) {
    int offset = start;
    int remain = length;
    while (remain > 0) {
      if (this.current.length == this.blockSize) {
        addBlock();
      }
      int toCopy = remain;
      int remainingInBlock = this.blockSize - this.current.length;
      if (remainingInBlock < toCopy) {
        toCopy = remainingInBlock;
      }
      System.arraycopy(chars, offset, this.current.chars, this.current.length, toCopy);
      offset += toCopy;
      remain -= toCopy;
      this.current.length += toCopy;
    }

    this.length += length;
    return this;
  }

  public CharBlockArray append(String s) {
    int remain = s.length();
    int offset = 0;
    while (remain > 0) {
      if (this.current.length == this.blockSize) {
        addBlock();
      }
      int toCopy = remain;
      int remainingInBlock = this.blockSize - this.current.length;
      if (remainingInBlock < toCopy) {
        toCopy = remainingInBlock;
      }
      s.getChars(offset, offset + toCopy, this.current.chars, this.current.length);
      offset += toCopy;
      remain -= toCopy;
      this.current.length += toCopy;
    }

    this.length += s.length();
    return this;
  }

  @Override
  public char charAt(int index) {
    Block b = blocks.get(blockIndex(index));
    return b.chars[indexInBlock(index)];
  }

  @Override
  public int length() {
    return this.length;
  }

  @Override
  public CharSequence subSequence(int start, int end) {
    int remaining = end - start;
    StringBuilder sb = new StringBuilder(remaining);
    int blockIdx = blockIndex(start);
    int indexInBlock = indexInBlock(start);
    while (remaining > 0) {
      Block b = blocks.get(blockIdx++);
      int numToAppend = Math.min(remaining, b.length - indexInBlock);
      sb.append(b.chars, indexInBlock, numToAppend);
      remaining -= numToAppend;
      indexInBlock = 0; // 2nd+ iterations read from start of the block 
    }
    return sb.toString();
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    for (Block b : blocks) {
      sb.append(b.chars, 0, b.length);
    }
    return sb.toString();
  }

  void flush(OutputStream out) throws IOException {
    ObjectOutputStream oos = null;
    try {
      oos = new ObjectOutputStream(out);
      oos.writeObject(this);
      oos.flush();
    } finally {
      if (oos != null) {
        oos.close();
      }
    }
  }

  public static CharBlockArray open(InputStream in) throws IOException, ClassNotFoundException {
    ObjectInputStream ois = null;
    try {
      ois = new ObjectInputStream(in);
      CharBlockArray a = (CharBlockArray) ois.readObject();
      return a;
    } finally {
      if (ois != null) {
        ois.close();
      }
    }
  }

}
