# Copyright 2017 The Cobalt Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Provides functionality common for all tools."""

import ctypes
import os
import re
import subprocess
import sys


def GetPath(name, **kwargs):
  """Computes a path to a tool.

  All tools understand the same 4 path-related arguments: 'path', 'dir',
  'prefix', and 'name'. When the 'path' argument is provided, it overrides the
  path to a tool. Otherwise, 'dir', 'prefix', and 'name' arguments, all of which
  are optional, are joined as {dir}/{prefix}{name} to compute the path.

  Args:
    name: A default name of a tool.
    **kwargs: A dictionary that optionally contains 'path', 'dir', 'prefix', and
        'name' arguments.

  Returns:
    The computed path.
  """
  if 'path' in kwargs:
    return kwargs['path']

  path = kwargs.get('prefix', '') + kwargs.get('name', name)
  if 'dir' in kwargs:
    path = os.path.join(kwargs['dir'], path)
  return path


def GetRuleName(rule_name_base, toolset):
  """Computes a Ninja name for target and host rules."""
  suffix = '' if toolset == 'target' else '_{0}'.format(toolset)
  return rule_name_base + suffix


def EstimateMaxConcurrentLinkers():
  """Estimates a number of dynamic linkers to run concurrently.

  The estimate takes into account available RAM and conservatively assumes that
  Chromium is being built.

  Returns:
    An estimated number of processes.
  """
  # TODO: Introduce _TryGetPhysicalMemoryInBytes().
  if sys.platform in ('win32', 'cygwin'):

    class MEMORYSTATUSEX(ctypes.Structure):
      _fields_ = [
          ('dwLength', ctypes.c_ulong),
          ('dwMemoryLoad', ctypes.c_ulong),
          ('ullTotalPhys', ctypes.c_ulonglong),
          ('ullAvailPhys', ctypes.c_ulonglong),
          ('ullTotalPageFile', ctypes.c_ulonglong),
          ('ullAvailPageFile', ctypes.c_ulonglong),
          ('ullTotalVirtual', ctypes.c_ulonglong),
          ('ullAvailVirtual', ctypes.c_ulonglong),
          ('sullAvailExtendedVirtual', ctypes.c_ulonglong),
      ]  # pylint: disable=invalid-name

    stat = MEMORYSTATUSEX()
    stat.dwLength = ctypes.sizeof(stat)
    ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(stat))

    # VS 2015 uses 20% more working set than VS 2013 and can consume all RAM
    # on a 64 GB machine.
    return max(1, stat.ullTotalPhys / (5 * (2**30)))  # total / 5GB
  elif sys.platform.startswith('linux'):
    if os.path.exists('/proc/meminfo'):
      with open('/proc/meminfo') as meminfo:
        memtotal_re = re.compile(r'^MemTotal:\s*(\d*)\s*kB')
        for line in meminfo:
          match = memtotal_re.match(line)
          if not match:
            continue
          # Allow 6Gb per link on Linux because Gold is quite memory hungry
          return max(1, int(match.group(1)) / (6 * (2**20)))
    return 1
  elif sys.platform == 'darwin':
    try:
      avail_bytes = int(subprocess.check_output(['sysctl', '-n', 'hw.memsize']))
      # A static library debug build of Chromium's unit_tests takes ~2.7GB, so
      # 4GB per ld process allows for some more bloat.
      return max(1, avail_bytes / (4 * (2**30)))  # total / 4GB
    except subprocess.CalledProcessError:
      return 1
  else:
    return 1
