"""
Enable optimizations specific to the platform (ex: sys.platform) and the Python
version (ex: sys.hexversion).

WARNING: On Python < 2.7.3 and < 3.2.2, sys.platform can be 'linux2' or
'linux3' depending on the major version of the Linux kernel. Ensure that
your application uses sys.platform.startswith("linux").
"""

import errno
import os
import platform
import socket
import struct
import sys
from astoptimizer.config import Function
from astoptimizer.compatibility import PYTHON2, INT_TYPES, PYTHON34
if PYTHON34:
    import enum

def add_module_constants(config, module_name, module, *prefixes):
    for name in dir(module):
        if not name.startswith(prefixes):
            continue
        fullname = "%s.%s" % (module_name, name)
        value = getattr(module, name)
        if PYTHON34 and isinstance(value, enum.Enum):
            value = value.value
        config.add_constant(fullname, value)

def setup_config(config):
    bits = struct.calcsize('L') * 8 - 1
    config.min_c_long = -2 ** bits
    config.max_c_long = 2 ** bits - 1

    config.add_constant('os.name', os.name)
    config.add_constant('sys.byteorder', sys.byteorder)
    config.add_constant('sys.platform', sys.platform)
    if PYTHON2:
        config.add_constant('sys.maxint', sys.maxint)
    config.add_constant('sys.maxsize', sys.maxsize)

    config.add_func('platform.machine', Function(platform.machine, 0))
    config.add_func('platform.release', Function(platform.release, 0))
    config.add_func('platform.system', Function(platform.system, 0))
    config.add_func('platform.version', Function(platform.version, 0))
    if sys.platform in ('darwin', 'win32'):
        # The filesystem encoding is always 'mbcs' on Windows
        # and 'utf-8' on Mac OS X
        config.add_func('sys.getfilesystemencoding',
                        Function(sys.getfilesystemencoding, 0))

    # os module
    add_module_constants(config, 'os', os, 'O_')
    for name in (
        'F_OK', 'R_OK', 'W_OK', 'X_OK', 'WNOHANG',
        'curdir', 'pardir', 'sep', 'altsep', 'pathsep',
        'linesep', 'devnull',
    ):
        if not hasattr(os, name):
            continue
        fullname = "os.%s" % name
        config.add_constant(fullname, getattr(os, name))

    config.add_constant('os.path.supports_unicode_filenames', os.path.supports_unicode_filenames)

    # errno: Add constants like errno.ENOENT
    add_module_constants(config, 'errno', errno, 'E')

    # socket: Add constants like socket.AF_INET and socket.SOCK_STREAM
    add_module_constants(config, 'socket', socket,
        'AF_', 'SOCK_', 'SOL_')

    config.add_func('socket.ntohl', Function(socket.ntohl, 1, INT_TYPES))
    config.add_func('socket.ntohs', Function(socket.ntohs, 1, INT_TYPES))
    config.add_func('socket.htonl', Function(socket.htonl, 1, INT_TYPES))
    config.add_func('socket.htons', Function(socket.htons, 1, INT_TYPES))

