/*
* 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.cassandra.io.util;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class SafeMemoryWriter extends DataOutputBuffer
{
    private SafeMemory memory;

    @SuppressWarnings("resource")
    public SafeMemoryWriter(long initialCapacity)
    {
        this(new SafeMemory(initialCapacity));
    }

    private SafeMemoryWriter(SafeMemory memory)
    {
        super(tailBuffer(memory).order(ByteOrder.BIG_ENDIAN));
        this.memory = memory;
    }

    public SafeMemory currentBuffer()
    {
        return memory;
    }

    @Override
    protected void reallocate(long count)
    {
        long newCapacity = calculateNewSize(count);
        if (newCapacity != capacity())
        {
            long position = length();
            ByteOrder order = buffer.order();

            SafeMemory oldBuffer = memory;
            memory = this.memory.copy(newCapacity);
            buffer = tailBuffer(memory);

            int newPosition = (int) (position - tailOffset(memory));
            buffer.position(newPosition);
            buffer.order(order);

            oldBuffer.free();
        }
    }

    public void setCapacity(long newCapacity)
    {
        reallocate(newCapacity);
    }

    public void close()
    {
        memory.close();
    }

    public Throwable close(Throwable accumulate)
    {
        return memory.close(accumulate);
    }

    public long length()
    {
        return tailOffset(memory) +  buffer.position();
    }

    public long capacity()
    {
        return memory.size();
    }

    @Override
    public SafeMemoryWriter order(ByteOrder order)
    {
        super.order(order);
        return this;
    }

    @Override
    public long validateReallocation(long newSize)
    {
        return newSize;
    }

    private static long tailOffset(Memory memory)
    {
        return Math.max(0, memory.size - Integer.MAX_VALUE);
    }

    private static ByteBuffer tailBuffer(Memory memory)
    {
        return memory.asByteBuffer(tailOffset(memory), (int) Math.min(memory.size, Integer.MAX_VALUE));
    }
}
