/***** BEGIN LICENSE BLOCK *****
 * Version: EPL 2.0/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Eclipse Public
 * 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.eclipse.org/legal/cpl-v10.html
 *
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 *
 *
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either of the GNU General Public License Version 2 or later (the "GPL"),
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the CPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the CPL, the GPL or the LGPL.
 ***** END LICENSE BLOCK *****/
/**
 * $Id: $
 */

package jnr.posix;

import jnr.constants.platform.Sysconf;
import jnr.constants.platform.Fcntl;
import jnr.ffi.Memory;
import jnr.ffi.Pointer;
import jnr.ffi.mapper.FromNativeContext;
import jnr.posix.util.MethodName;

import java.io.FileDescriptor;
import java.nio.ByteBuffer;
import jnr.constants.platform.Confstr;
import jnr.constants.platform.Pathconf;

final class AixPOSIX extends BaseNativePOSIX {
    // These should probably be put into jnr-constants instead eventually, but
    // they're here for now as a one-off to work around AIX flock issues
    private enum FlockFlags {
        LOCK_SH(1),
        LOCK_EX(2),
        LOCK_NB(4),
        LOCK_UN(8);
        private final int value;
        FlockFlags(int value) {
            this.value = value;
        }
        public final int intValue() {
            return value;
        }
    }

    AixPOSIX(LibCProvider libc, POSIXHandler handler) {
        super(libc, handler);
    }

    public FileStat allocateStat() { 
        return new AixFileStat(this); 
    }

    public MsgHdr allocateMsgHdr() {
        handler.unimplementedError(MethodName.getCallerMethodName());
        return null;
    }

    public SocketMacros socketMacros() {
        handler.unimplementedError(MethodName.getCallerMethodName());
        return null;
    }

    public long sysconf(Sysconf name) {
        return libc().sysconf(name);
    }

    public int confstr(Confstr name, ByteBuffer buf, int len) {
        return libc().confstr(name, buf, len);
    }

    public int fpathconf(int fd, Pathconf name) {
        return libc().fpathconf(fd, name);
    }

    public Times times() {
        return NativeTimes.times(this);
    }


    public static final PointerConverter PASSWD = new PointerConverter() {
        public Object fromNative(Object arg, FromNativeContext ctx) {
            return arg != null ? new AixPasswd((Pointer) arg) : null;
        }
    };

    public Pointer allocatePosixSpawnFileActions() {
        return Memory.allocateDirect(getRuntime(), 4);
    }

    public Pointer allocatePosixSpawnattr() {
        return Memory.allocateDirect(getRuntime(), 60);
    }

    // AIX flock lives in libbsd instead of libc.  AIX flock locks fully
    // interact with fcntl locks, so we can implement flock in terms of fcntl,
    // which is what we do here to avoid having to pull in that lib.
    @Override
    public int flock(int fd, int operation) {
        int cmd = Fcntl.F_SETLKW.intValue();
        short type = 0;

        // Map the flock call flags to a fcntl flock type flag
        if ((operation & FlockFlags.LOCK_SH.intValue()) != 0) {
            type = (short)Fcntl.F_RDLCK.intValue();
        } else if ((operation & FlockFlags.LOCK_EX.intValue()) != 0) {
            type = (short)Fcntl.F_WRLCK.intValue();
        } else if ((operation & FlockFlags.LOCK_UN.intValue()) != 0) {
            type = (short)Fcntl.F_UNLCK.intValue();
        }

        // Switch to the fcntl non-blocking command
        if ((operation & FlockFlags.LOCK_NB.intValue()) != 0) {
            cmd = Fcntl.F_SETLK.intValue();
        }

        Flock flock = allocateFlock();
        flock.type(type);
        flock.whence((short)0);
        flock.start(0);
        flock.len(0);
        return libc().fcntl(fd, cmd, flock);
    }

    @Override
    public Timeval allocateTimeval() { return new AixTimeval(getRuntime()); }

    // This isn't an override yet, because Flock would have to be implemented
    // for all platforms, or at least with a DefaultNative implementation.  This
    // is fine for now, because only AIX uses the flock structure
    public Flock allocateFlock() { return new AixFlock(getRuntime()); }
}
