# Copyright (c) 2005 The Regents of The University of Michigan
# Copyright (c) 2010 Advanced Micro Devices, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Nathan Binkert
#          Gabe Black

# metric prefixes
atto  = 1.0e-18
femto = 1.0e-15
pico  = 1.0e-12
nano  = 1.0e-9
micro = 1.0e-6
milli = 1.0e-3

kilo = 1.0e3
mega = 1.0e6
giga = 1.0e9
tera = 1.0e12
peta = 1.0e15
exa  = 1.0e18

# power of 2 prefixes
kibi = 1024
mebi = kibi * 1024
gibi = mebi * 1024
tebi = gibi * 1024
pebi = tebi * 1024
exbi = pebi * 1024

metric_prefixes = {
    'Ei': exbi,
    'E': exa,
    'Pi': pebi,
    'P': peta,
    'Ti': tebi,
    'T': tera,
    'Gi': gibi,
    'G': giga,
    'M': mega,
    'ki': kibi,
    'k': kilo,
    'Mi': mebi,
    'm': milli,
    'u': micro,
    'n': nano,
    'p': pico,
    'f': femto,
    'a': atto,
}

binary_prefixes = {
    'Ei': exbi,
    'E' : exbi,
    'Pi': pebi,
    'P' : pebi,
    'Ti': tebi,
    'T' : tebi,
    'Gi': gibi,
    'G' : gibi,
    'Mi': mebi,
    'M' : mebi,
    'ki': kibi,
    'k' : kibi,
}

def assertStr(value):
    if not isinstance(value, str):
        raise TypeError("wrong type '%s' should be str" % type(value))


# memory size configuration stuff
def toFloat(value, target_type='float', units=None, prefixes=[]):
    assertStr(value)

    if units and not value.endswith(units):
        units = None
    if not units:
        try:
            return float(value)
        except ValueError:
            raise ValueError("cannot convert '%s' to %s" % \
                             (value, target_type))

    value = value[:-len(units)]

    prefix = next((p for p in prefixes.keys() if value.endswith(p)), None)
    if not prefix:
        return float(value)
    value = value[:-len(prefix)]

    return float(value) * prefixes[prefix]

def toMetricFloat(value, target_type='float', units=None):
    return toFloat(value, target_type, units, metric_prefixes)

def toBinaryFloat(value, target_type='float', units=None):
    return toFloat(value, target_type, units, binary_prefixes)

def toInteger(value, target_type='integer', units=None, prefixes=[]):
    value = toFloat(value, target_type, units, prefixes)
    result = long(value)
    if value != result:
        raise ValueError("cannot convert '%s' to integer %s" % \
                (value, target_type))

    return result

def toMetricInteger(value, target_type='integer', units=None):
    return toInteger(value, target_type, units, metric_prefixes)

def toBinaryInteger(value, target_type='integer', units=None):
    return toInteger(value, target_type, units, binary_prefixes)

def toBool(value):
    assertStr(value)

    value = value.lower()
    if value in ('true', 't', 'yes', 'y', '1'):
        return True
    if value in ('false', 'f', 'no', 'n', '0'):
        return False
    return result

def toFrequency(value):
    return toMetricFloat(value, 'frequency', 'Hz')

def toLatency(value):
    return toMetricFloat(value, 'latency', 's')

def anyToLatency(value):
    """result is a clock period"""
    try:
        return 1 / toFrequency(value)
    except (ValueError, ZeroDivisionError):
        pass

    try:
        return toLatency(value)
    except ValueError:
        pass

    raise ValueError("cannot convert '%s' to clock period" % value)

def anyToFrequency(value):
    """result is a clock period"""
    try:
        return toFrequency(value)
    except ValueError:
        pass

    try:
        return 1 / toLatency(value)
    except ValueError as ZeroDivisionError:
        pass

    raise ValueError("cannot convert '%s' to clock period" % value)

def toNetworkBandwidth(value):
    return toMetricFloat(value, 'network bandwidth', 'bps')

def toMemoryBandwidth(value):
    return toBinaryFloat(value, 'memory bandwidth', 'B/s')

def toMemorySize(value):
    return toBinaryInteger(value, 'memory size', 'B')

def toIpAddress(value):
    if not isinstance(value, str):
        raise TypeError("wrong type '%s' should be str" % type(value))

    bytes = value.split('.')
    if len(bytes) != 4:
        raise ValueError('invalid ip address %s' % value)

    for byte in bytes:
        if not 0 <= int(byte) <= 0xff:
            raise ValueError('invalid ip address %s' % value)

    return (int(bytes[0]) << 24) | (int(bytes[1]) << 16) | \
           (int(bytes[2]) << 8)  | (int(bytes[3]) << 0)

def toIpNetmask(value):
    if not isinstance(value, str):
        raise TypeError("wrong type '%s' should be str" % type(value))

    (ip, netmask) = value.split('/')
    ip = toIpAddress(ip)
    netmaskParts = netmask.split('.')
    if len(netmaskParts) == 1:
        if not 0 <= int(netmask) <= 32:
            raise ValueError('invalid netmask %s' % netmask)
        return (ip, int(netmask))
    elif len(netmaskParts) == 4:
        netmaskNum = toIpAddress(netmask)
        if netmaskNum == 0:
            return (ip, 0)
        testVal = 0
        for i in range(32):
            testVal |= (1 << (31 - i))
            if testVal == netmaskNum:
                return (ip, i + 1)
        raise ValueError('invalid netmask %s' % netmask)
    else:
        raise ValueError('invalid netmask %s' % netmask)

def toIpWithPort(value):
    if not isinstance(value, str):
        raise TypeError("wrong type '%s' should be str" % type(value))

    (ip, port) = value.split(':')
    ip = toIpAddress(ip)
    if not 0 <= int(port) <= 0xffff:
        raise ValueError('invalid port %s' % port)
    return (ip, int(port))

def toVoltage(value):
    return toMetricFloat(value, 'voltage', 'V')

def toCurrent(value):
    return toMetricFloat(value, 'current', 'A')

def toEnergy(value):
    return toMetricFloat(value, 'energy', 'J')
