/*
 *  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.tomcat.util.buf;

import java.io.Serializable;

/**
 * Base class for the *Chunk implementation to reduce duplication.
 */
public abstract class AbstractChunk implements Cloneable, Serializable {

    private static final long serialVersionUID = 1L;

    /*
     * JVMs may limit the maximum array size to slightly less than
     * Integer.MAX_VALUE. On markt's desktop the limit is MAX_VALUE - 2.
     * Comments in the JRE source code for ArrayList and other classes indicate
     * that it may be as low as MAX_VALUE - 8 on some systems.
     */
    public static final int ARRAY_MAX_SIZE = Integer.MAX_VALUE - 8;

    private int hashCode = 0;
    protected boolean hasHashCode = false;

    protected boolean isSet;

    private int limit = -1;

    protected int start;
    protected int end;


    /**
     * Maximum amount of data in this buffer. If -1 or not set, the buffer will
     * grow to {{@link #ARRAY_MAX_SIZE}. Can be smaller than the current buffer
     * size ( which will not shrink ). When the limit is reached, the buffer
     * will be flushed (if out is set) or throw exception.
     *
     * @param limit The new limit
     */
    public void setLimit(int limit) {
        this.limit = limit;
    }


    public int getLimit() {
        return limit;
    }


    protected int getLimitInternal() {
        if (limit > 0) {
            return limit;
        } else {
            return ARRAY_MAX_SIZE;
        }
    }


    /**
     * @return the start position of the data in the buffer
     */
    public int getStart() {
        return start;
    }


    public int getEnd() {
        return end;
    }


    public void setEnd(int i) {
        end = i;
    }


    // TODO: Deprecate offset and use start

    public int getOffset() {
        return start;
    }


    public void setOffset(int off) {
        if (end < off) {
            end = off;
        }
        start = off;
    }


    /**
     * @return the length of the data in the buffer
     */
    public int getLength() {
        return end - start;
    }


    public boolean isNull() {
        if (end > 0) {
            return false;
        }
        return !isSet;
    }


    public int indexOf(String src, int srcOff, int srcLen, int myOff) {
        char first = src.charAt(srcOff);

        // Look for first char
        int srcEnd = srcOff + srcLen;

        mainLoop: for (int i = myOff + start; i <= (end - srcLen); i++) {
            if (getBufferElement(i) != first) {
                continue;
            }
            // found first char, now look for a match
            int myPos = i + 1;
            for (int srcPos = srcOff + 1; srcPos < srcEnd;) {
                if (getBufferElement(myPos++) != src.charAt(srcPos++)) {
                    continue mainLoop;
                }
            }
            return i - start; // found it
        }
        return -1;
    }


    /**
     * Resets the chunk to an uninitialized state.
     */
    public void recycle() {
        hasHashCode = false;
        isSet = false;
        start = 0;
        end = 0;
    }


    @Override
    public int hashCode() {
        if (hasHashCode) {
            return hashCode;
        }
        int code = 0;

        code = hash();
        hashCode = code;
        hasHashCode = true;
        return code;
    }


    public int hash() {
        int code = 0;
        for (int i = start; i < end; i++) {
            code = code * 37 + getBufferElement(i);
        }
        return code;
    }


    protected abstract int getBufferElement(int index);
}
