# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

# This file contains a set of utilities functions used by other Python-based
# scripts.

import os
import platform
import queue
import re
import subprocess
import sys
import threading
import time

from io import StringIO
from subprocess import getoutput

# Try to guess the host operating system.
def GuessOS():
    id = platform.system()
    if id == "Linux":
        return "linux"
    elif id == "Darwin":
        return "macos"
    elif id == "Windows" or id == "Microsoft":
        # On Windows Vista platform.system() can return "Microsoft" with some
        # versions of Python, see http://bugs.python.org/issue1082 for details.
        return "win32"
    elif id == 'FreeBSD':
        return 'freebsd'
    elif id == 'OpenBSD':
        return 'openbsd'
    elif id == 'SunOS':
        return 'solaris'
    else:
        return None


# Try to guess the host architecture.
def GuessArchitecture():
    id = platform.machine()
    if id.startswith('arm'):
        return 'arm'
    elif (not id) or (not re.match('(x|i[3-6])86', id) is None):
        return 'ia32'
    elif id == 'i86pc':
        return 'ia32'
    else:
        return None


# Try to guess the number of cpus on this machine.
def GuessCpus():
    if os.path.exists("/proc/cpuinfo"):
        return int(
            getoutput(
                "GREP_OPTIONS= grep -E '^processor' /proc/cpuinfo | wc -l"))
    if os.path.exists("/usr/bin/hostinfo"):
        return int(
            getoutput(
                '/usr/bin/hostinfo | GREP_OPTIONS= grep "processors are logically available." | awk "{ print \$1 }"'
            ))
    win_cpu_count = os.getenv("NUMBER_OF_PROCESSORS")
    if win_cpu_count:
        return int(win_cpu_count)
    return int(os.getenv("DART_NUMBER_OF_CORES", 2))


# Returns true if we're running under Windows.
def IsWindows():
    return GuessOS() == 'win32'


# Reads a text file into an array of strings - one for each
# line. Strips comments in the process.
def ReadLinesFrom(name):
    result = []
    for line in open(name):
        if '#' in line:
            line = line[:line.find('#')]
        line = line.strip()
        if len(line) == 0:
            continue
        result.append(line)
    return result


# Filters out all arguments until the next '--' argument
# occurs.
def ListArgCallback(option, opt_str, value, parser):
    if value is None:
        value = []

    for arg in parser.rargs:
        if arg[:2].startswith('--'):
            break
        value.append(arg)

    del parser.rargs[:len(value)]
    setattr(parser.values, option.dest, value)


# Filters out all argument until the first non '-' or the
# '--' argument occurs.
def ListDashArgCallback(option, opt_str, value, parser):
    if value is None:
        value = []

    for arg in parser.rargs:
        if arg[:2].startswith('--') or arg[0] != '-':
            break
        value.append(arg)

    del parser.rargs[:len(value)]
    setattr(parser.values, option.dest, value)


# Mapping table between build mode and build configuration.
BUILD_MODES = {
    'debug': 'Debug',
    'release': 'Release',
}

# Mapping table between OS and build output location.
BUILD_ROOT = {
    'linux': os.path.join('out'),
    'freebsd': os.path.join('out'),
    'macos': os.path.join('xcodebuild'),
}


def GetBuildMode(mode):
    global BUILD_MODES
    return BUILD_MODES[mode]


def GetBuildConf(mode, arch):
    return GetBuildMode(mode) + arch.upper()


def GetBuildRoot(host_os, mode=None, arch=None, sanitizer=None):
    global BUILD_ROOT
    if mode:
        return os.path.join(BUILD_ROOT[host_os],
                            GetBuildConf(mode, arch, sanitizer))
    else:
        return BUILD_ROOT[host_os]


def RunCommand(command,
               input=None,
               pollFn=None,
               outStream=None,
               errStream=None,
               killOnEarlyReturn=True,
               verbose=False,
               debug=False,
               printErrorInfo=False):
    """
  Run a command, with optional input and polling function.

  Args:
    command: list of the command and its arguments.
    input: optional string of input to feed to the command, it should be
        short enough to fit in an i/o pipe buffer.
    pollFn: if present will be called occasionally to check if the command
        should be finished early. If pollFn() returns true then the command
        will finish early.
    outStream: if present, the stdout output of the command will be written to
        outStream.
    errStream: if present, the stderr output of the command will be written to
        errStream.
    killOnEarlyReturn: if true and pollFn returns true, then the subprocess will
        be killed, otherwise the subprocess will be detached.
    verbose: if true, the command is echoed to stderr.
    debug: if true, prints debugging information to stderr.
    printErrorInfo: if true, prints error information when the subprocess
    returns a non-zero exit code.
  Returns: the output of the subprocess.

  Exceptions:
    Raises Error if the subprocess returns an error code.
    Raises ValueError if called with invalid arguments.
  """
    if verbose:
        sys.stderr.write("command %s\n" % command)
    stdin = None
    if input:
        stdin = subprocess.PIPE
    try:
        process = subprocess.Popen(
            args=command,
            stdin=stdin,
            bufsize=1,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE)
    except OSError as e:
        if not isinstance(command, str):
            command = ' '.join(command)
        if printErrorInfo:
            sys.stderr.write("Command failed: '%s'\n" % command)
        raise Error(e)

    def StartThread(out):
        queue = queue.Queue()

        def EnqueueOutput(out, queue):
            for line in iter(out.readline, b''):
                queue.put(line)
            out.close()

        thread = threading.Thread(target=EnqueueOutput, args=(out, queue))
        thread.daemon = True
        thread.start()
        return queue

    outQueue = StartThread(process.stdout)
    errQueue = StartThread(process.stderr)

    def ReadQueue(queue, out, out2):
        try:
            while True:
                line = queue.get(False)
                out.write(line)
                if out2 != None:
                    out2.write(line)
        except queue.Empty:
            pass

    outBuf = StringIO.StringIO()
    errorBuf = StringIO.StringIO()
    if input:
        process.stdin.write(input)
    while True:
        returncode = process.poll()
        if returncode != None:
            break
        ReadQueue(errQueue, errorBuf, errStream)
        ReadQueue(outQueue, outBuf, outStream)
        if pollFn != None and pollFn():
            returncode = 0
            if killOnEarlyReturn:
                process.kill()
            break
        time.sleep(0.1)
    # Drain queue
    ReadQueue(errQueue, errorBuf, errStream)
    ReadQueue(outQueue, outBuf, outStream)

    out = outBuf.getvalue()
    error = errorBuf.getvalue()
    if returncode:
        if not isinstance(command, str):
            command = ' '.join(command)
        if printErrorInfo:
            sys.stderr.write("Command failed: '%s'\n" % command)
            sys.stderr.write("        stdout: '%s'\n" % out)
            sys.stderr.write("        stderr: '%s'\n" % error)
            sys.stderr.write("    returncode: %d\n" % returncode)
        raise Error("Command failed: %s" % command)
    if debug:
        sys.stderr.write("output: %s\n" % out)
    return out


def Main(argv):
    print("GuessOS() -> ", GuessOS())
    print("GuessArchitecture() -> ", GuessArchitecture())
    print("GuessCpus() -> ", GuessCpus())
    print("IsWindows() -> ", IsWindows())


class Error(Exception):
    pass


if __name__ == "__main__":
    import sys
    Main(sys.argv)
