package com.headius.backport9.buffer;

import java.nio.Buffer;

/**
 * Utility functions to help avoid binary incompatibility due to variadic return types on Java 9.
 *
 * Java 9 introduced new overloads of several Buffer methods on its subclasses. Because those methods
 * return the actual type of the subclass, they are incompatible with Java 8 where no such overloads
 * exist. This utility casts all buffers to Buffer and makes the call from there, avoiding binding
 * directly to the overloads that don't exist on Java 8.
 */
public class Buffers {
    /**
     * Invoke Buffer.clear always using Buffer as the target, to avoid binary incompatibility on Java 8.
     *
     * @param buf the buffer
     * @param <T> any java.nio.Buffer type
     * @return the buffer
     * @see Buffer#clear()
     */
    public static <T extends Buffer> T clearBuffer(T buf) {
        return (T) buf.clear();
    }

    /**
     * Invoke Buffer.flip always using Buffer as the target, to avoid binary incompatibility on Java 8.
     *
     * @param buf the buffer
     * @param <T> any java.nio.Buffer type
     * @return the buffer
     * @see Buffer#flip()
     */
    public static <T extends Buffer> T flipBuffer(T buf) {
        return (T) buf.flip();
    }

    /**
     * Invoke Buffer.limit always using Buffer as the target, to avoid binary incompatibility on Java 8.
     *
     * @param buf the buffer
     * @param limit the new limit
     * @param <T> any java.nio.Buffer type
     * @return the buffer
     * @see Buffer#limit(int)
     */
    public static <T extends Buffer> T limitBuffer(T buf, int limit) {
        return (T) buf.limit(limit);
    }

    /**
     * Invoke Buffer.position always using Buffer as the target, to avoid binary incompatibility on Java 8.
     *
     * @param buf the buffer
     * @param limit the new limit
     * @param <T> any java.nio.Buffer type
     * @return the buffer
     * @see Buffer#position()
     */
    public static <T extends Buffer> T positionBuffer(T buf, int limit) {
        return (T) buf.position(limit);
    }

    /**
     * Invoke Buffer.mark always using Buffer as the target, to avoid binary incompatibility on Java 8.
     *
     * @param buf the buffer
     * @param <T> any java.nio.Buffer type
     * @return the buffer
     * @see Buffer#mark()
     */
    public static <T extends Buffer> T markBuffer(T buf) {
        return (T) buf.mark();
    }

    /**
     * Invoke Buffer.rewind always using Buffer as the target, to avoid binary incompatibility on Java 8.
     *
     * @param buf the buffer
     * @param <T> any java.nio.Buffer type
     * @return the buffer
     * @see Buffer#rewind()
     */
    public static <T extends Buffer> T rewindBuffer(T buf) {
        return (T) buf.rewind();
    }
}
