package jnr.posix;

import jnr.ffi.Library;
import jnr.ffi.LibraryLoader;
import jnr.ffi.LibraryOption;
import jnr.ffi.Struct;

import java.util.Collections;
import java.util.HashMap;

import jnr.ffi.mapper.FunctionMapper;
import jnr.posix.util.DefaultPOSIXHandler;
import jnr.posix.util.Platform;

import java.util.Map;

public class POSIXFactory {
    // Weird inner-class resolution problem work-around FIXME: JRUBY-5889.  Someone fix JAFFL!
    private static final Class<Struct> BOGUS_HACK = Struct.class;
    public static final jnr.ffi.Platform NATIVE_PLATFORM = jnr.ffi.Platform.getNativePlatform();
    public static final String STANDARD_C_LIBRARY_NAME = NATIVE_PLATFORM.getStandardCLibraryName();

    /**
     * Get a POSIX instance. If useNativePosix is true, this works just like
     * POSIXFactory#getPOSIX(). If useNativePosix is false, this works like
     * POSIXFactory#getJavaPOSIX()
     *
     * @param handler a POSIXHandler implementation
     * @param useNativePOSIX whether to attempt to use native code for better functionality
     * @return a POSIX implementation, attempting to use native code if useNativePosix is true
     */
    public static POSIX getPOSIX(POSIXHandler handler, boolean useNativePOSIX) {
        return new LazyPOSIX(handler, useNativePOSIX);
    }

    /**
     * This will use {@link DefaultPOSIXHandler} and the native POSIX implementation,
     * falling back on the pure-Java implementation if native support is not available.
     *
     * @return a POSIX implementation, native if possible and pure-Java otherwise.
     */
    public static POSIX getPOSIX() {
        return getPOSIX(new DefaultPOSIXHandler(), true);
    }

    /**
     * Get a pure-Java POSIX instance. Functionality will be limited to that which can
     * be provided by pure-Java/JDK features or shelling out to external commands.
     *
     * @param handler a POSIXHandler implementation
     * @return a pure-Java POSIX implementation
     */
    public static POSIX getJavaPOSIX(POSIXHandler handler) {
        return new JavaPOSIX(handler);
    }

    /**
     * Get a pure-Java POSIX instance. Functionality will be limited to that which can
     * be provided by pure-Java/JDK features or shelling out to external commands.
     *
     * @return a pure-Java POSIX implementation
     */
    public static POSIX getJavaPOSIX() {
        return getJavaPOSIX(new DefaultPOSIXHandler());
    }

    /**
     * Get a POSIX instance. If a true native implementation can't be loaded, allow that
     * error to propagate rather than falling back on the pure-Java version.
     *
     * @param handler a POSIXHandler implementation
     * @return a native POSIX implementation, raising errors if the native version can't load
     */
    public static POSIX getNativePOSIX(POSIXHandler handler) {
        return loadNativePOSIX(handler);
    }

    /**
     * Get a POSIX instance. If a true native implementation can't be loaded, allow that
     * error to propagate rather than falling back on the pure-Java version.
     *
     * @return a native POSIX implementation, raising errors if the native version can't load
     */
    public static POSIX getNativePOSIX() {
        return getNativePOSIX(new DefaultPOSIXHandler());
    }

    static POSIX loadPOSIX(POSIXHandler handler, boolean useNativePOSIX) {
        POSIX posix = null;

        if (useNativePOSIX) {
            try {
                posix = loadNativePOSIX(handler);
                posix = posix != null ? new CheckedPOSIX(posix, handler) : null;
                // ENEBO: Should printing be done through a handler+log method?
                if (handler.isVerbose()) {
                    if (posix != null) {
                        System.err.println("Successfully loaded native POSIX impl.");
                    } else {
                        System.err.println("Failed to load native POSIX impl; falling back on Java impl. Unsupported OS.");
                    }
                }
            } catch (Throwable t) {
                if (handler.isVerbose()) {
                    System.err.println("Failed to load native POSIX impl; falling back on Java impl. Stacktrace follows.");
                    t.printStackTrace();
                }
            }
        }

        if (posix == null) {
            posix = getJavaPOSIX(handler);
        }

        return posix;
    }
    
    private static POSIX loadNativePOSIX(POSIXHandler handler) {
        switch (NATIVE_PLATFORM.getOS()) {
            case DARWIN:
                return loadMacOSPOSIX(handler);

            case LINUX:
                return loadLinuxPOSIX(handler);

            case FREEBSD:
                return loadFreeBSDPOSIX(handler);

            case DRAGONFLY:
                return loadDragonFlyPOSIX(handler);
            
            case OPENBSD:
                return loadOpenBSDPOSIX(handler);

            case SOLARIS:
                return loadSolarisPOSIX(handler);
            
            case AIX:
                return loadAixPOSIX(handler);
            
            case WINDOWS:
                return loadWindowsPOSIX(handler);
        }

        return null;
    }

    public static POSIX loadLinuxPOSIX(POSIXHandler handler) {
        return new LinuxPOSIX(DefaultLibCProvider.INSTANCE, handler);
    }

    public static POSIX loadMacOSPOSIX(POSIXHandler handler) {
        return new MacOSPOSIX(DefaultLibCProvider.INSTANCE, handler);
    }

    public static POSIX loadSolarisPOSIX(POSIXHandler handler) {
        return new SolarisPOSIX(DefaultLibCProvider.INSTANCE, handler);
    }

    public static POSIX loadFreeBSDPOSIX(POSIXHandler handler) {
        return new FreeBSDPOSIX(DefaultLibCProvider.INSTANCE, handler);
    }

    public static POSIX loadDragonFlyPOSIX(POSIXHandler handler) {
        return new DragonFlyPOSIX(DefaultLibCProvider.INSTANCE, handler);
    }

    public static POSIX loadOpenBSDPOSIX(POSIXHandler handler) {
        return new OpenBSDPOSIX(DefaultLibCProvider.INSTANCE, handler);
    }

    public static POSIX loadWindowsPOSIX(POSIXHandler handler) {
        return new WindowsPOSIX(DefaultLibCProvider.INSTANCE, handler);
    }

    public static POSIX loadAixPOSIX(POSIXHandler handler) {
        return new AixPOSIX(DefaultLibCProvider.INSTANCE, handler);
    }
    
    private static String[] libraries() {
        switch (NATIVE_PLATFORM.getOS()) {
            case LINUX:
                return new String[] {STANDARD_C_LIBRARY_NAME};

            case SOLARIS:
                return new String[] { "socket", "nsl", STANDARD_C_LIBRARY_NAME};

            case DRAGONFLY:
            case FREEBSD:
            case NETBSD:
                return new String[] {STANDARD_C_LIBRARY_NAME};
            
            case AIX:
                return jnr.ffi.Runtime.getSystemRuntime().addressSize() == 4
                    ? new String[] { "libc.a(shr.o)" }
                    : new String[] { "libc.a(shr_64.o)" };
            
            case WINDOWS:
                return new String[] { "msvcrt", "kernel32" };

            default:
                return new String[] {STANDARD_C_LIBRARY_NAME};
        }
    }
    
    private static Class<? extends LibC> libraryInterface() {
        switch (NATIVE_PLATFORM.getOS()) {
            case LINUX:
                return LinuxLibC.class;
            
            case AIX:
                return AixLibC.class;
            
            case SOLARIS:
                return SolarisLibC.class;

            case WINDOWS:
                return WindowsLibC.class;

            default:
                return UnixLibC.class;
        }
    }

    private static FunctionMapper functionMapper() {
        switch (NATIVE_PLATFORM.getOS()) {
            case AIX:
                return new SimpleFunctionMapper.Builder()
                        .map("stat", "stat64x")
                        .map("fstat", "fstat64x")
                        .map("lstat", "lstat64x")
                        .map("stat64", "stat64x")
                        .map("fstat64", "fstat64x")
                        .map("lstat64", "lstat64x")
                        .build();
            
            case WINDOWS:
                return new SimpleFunctionMapper.Builder()
                        .map("getpid", "_getpid")
                        .map("chmod", "_chmod")
                        .map("fstat", "_fstat64")
                        .map("stat", "_stat64")
                        .map("umask", "_umask")
                        .map("isatty", "_isatty")
                        .map("read", "_read")
                        .map("write", "_write")
                        .map("close", "_close")
                        .map("getcwd", "_getcwd")
                        .map("unlink", "_unlink")
                        .map("access", "_access")
                        .map("open", "_open")
                        .map("dup", "_dup")
                        .map("dup2", "_dup2")
                        .map("lseek", "_lseek")
                        .map("ftruncate", "_chsize")
                        .build();
            
            case SOLARIS:
                return Platform.IS_32_BIT 
                    ? new SimpleFunctionMapper.Builder()
                        .map("stat", "stat64")
                        .map("fstat", "fstat64")
                        .map("lstat", "lstat64")
                        .build()
                    : null;
            default:
                return null;
        }
    }
    
    private static Map<LibraryOption, Object> options() {
        Map<LibraryOption, Object> options = new HashMap<LibraryOption, Object>();
        
        FunctionMapper functionMapper = functionMapper();
        if (functionMapper != null) {
            options.put(LibraryOption.FunctionMapper, functionMapper);
        }

        options.put(LibraryOption.TypeMapper, POSIXTypeMapper.INSTANCE);
        options.put(LibraryOption.LoadNow, Boolean.TRUE);
        
        return Collections.unmodifiableMap(options);
    }

    private static final class DefaultLibCProvider implements LibCProvider {
        public static final LibCProvider INSTANCE = new DefaultLibCProvider();

        private static final class SingletonHolder {
            public static LibC libc;
            public static Crypt crypt;
            static {
                LibraryLoader<? extends LibC> libcLoader = LibraryLoader.create(libraryInterface());

                // always do a default search
                libcLoader.searchDefault();

                for (String library : libraries()) {
                    libcLoader.library(library);
                }

                for (Map.Entry<LibraryOption, Object> entry : options().entrySet()) {
                    libcLoader.option(entry.getKey(), entry.getValue());
                }

                libcLoader.failImmediately();

                libc = libcLoader.load();

                Crypt c = null;

                // FIXME: This is kinda gross but there's no way to tell jnr-ffi that some libraries are ok to fail
                // See jruby/jruby#5447.
                try {
                    LibraryLoader<Crypt> loader = LibraryLoader.create(Crypt.class).failImmediately();
                    c = loader.load("libcrypt.so.1");
                } catch (UnsatisfiedLinkError ule) {
                    try {
                        LibraryLoader<Crypt> loader = LibraryLoader.create(Crypt.class).failImmediately();
                        c = loader.load("crypt");
                    } catch (UnsatisfiedLinkError ule2) {
                        try {
                            LibraryLoader<Crypt> loader = LibraryLoader.create(Crypt.class).failImmediately();
                            c = loader.load(STANDARD_C_LIBRARY_NAME);
                        } catch (UnsatisfiedLinkError ule3) {
                            // TODO: log somewhere? Warning?
                        }
                    }
                }

                crypt = c;
            }
        }

        public final LibC getLibC() {
            return SingletonHolder.libc;
        }

        public final Crypt getCrypt() {
            return SingletonHolder.crypt;
        }
    }
}
