# Copyright (C) 2009 Kevin Ollivier  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. 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.
#
# THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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.
#
# This module is for code where we override waf's default behavior or extend waf

import os
import subprocess
import sys

import Utils


# version of exec_command that handles Windows command lines longer than 32000 chars
def exec_command(s, **kw):
    filename = ''
    if sys.platform.startswith('win') and len(' '.join(s)) > 32000:
        import tempfile
        (fd, filename) = tempfile.mkstemp()
        t = []
        for i in s:
            if i.find(" ") != -1:
                i = '"%s"' % i
            t.append(i)

        t1 = t[1:]
        # Fix for LNK1170 error
        filename_str = '@' + filename
        filename2_str = None
        if len(' '.join(s)) > 131070:
            t2 = t[len(t) / 2:]
            t1 = t[1:len(t) / 2]
            (fd2, filename2) = tempfile.mkstemp()
            os.write(fd2, ' '.join(t2))
            os.close(fd2)
            filename2_str = '@' + filename2
        os.write(fd, ' '.join(t1))
        os.close(fd)

        s = [s[0]]
        s.append(filename_str)
        if filename2_str:
            s.append(filename2_str)

    if 'log' in kw:
        kw['stdout'] = kw['stderr'] = kw['log']
        del(kw['log'])
    kw['shell'] = isinstance(s, str)

    def cleanup():
        try:
            if os.path.exists(filename):
                os.remove(filename)
        except:
            pass

    try:
        proc = subprocess.Popen(s, **kw)
        result = proc.wait()
        cleanup()
        return result

    except OSError:
        cleanup()
        raise

Utils.exec_command = exec_command

# Better performing h_file to keep hashing from consuming lots of time
import stat


def h_file(filename):
    st = os.stat(filename)
    if stat.S_ISDIR(st[stat.ST_MODE]):
        raise IOError('not a file')
    m = Utils.md5()
    m.update(str(st.st_mtime))
    m.update(str(st.st_size))
    m.update(filename)
    return m.digest()

Utils.h_file = h_file
