# Copyright 2017 Google Inc. 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.
"""Allows to use Clang as a compiler and assembler."""

from starboard.tools.toolchain import abstract
from starboard.tools.toolchain import common


class CompilerBase(object):
  """A base class for Clang-based compilers and assemblers."""

  def __init__(self, **kwargs):
    self._path = common.GetPath('clang', **kwargs)
    self._extra_flags = kwargs.get('extra_flags', [])

  def GetPath(self):
    return self._path

  def GetExtraFlags(self):
    return self._extra_flags

  def GetMaxConcurrentProcesses(self):
    # Run as much concurrent processes as possible.
    return None

  def GetHeaderDependenciesFilePath(self):
    return '$out.d'

  def GetHeaderDependenciesFormat(self):
    return 'gcc'

  def GetRspFilePath(self):
    # A command line only contains one input and one output file.
    pass

  def GetRspFileContent(self):
    # A command line only contains one input and one output file.
    pass


class CCompiler(CompilerBase, abstract.CCompiler):
  """Compiles C sources using Clang."""

  def __init__(self, **kwargs):
    super(CCompiler, self).__init__(**kwargs)

  def GetCommand(self, path, extra_flags, flags):
    return '{0} -x c -MMD -MF $out.d {1} {2} -c $in -o $out'.format(
        path, extra_flags, flags)

  def GetDescription(self):
    return 'CC $out'

  def GetFlags(self, defines, include_dirs, cflags):
    define_flags = ['-D{0}'.format(define) for define in defines]
    include_dir_flags = [
        '-I{0}'.format(include_dir) for include_dir in include_dirs
    ]
    return define_flags + include_dir_flags + cflags


class CxxCompiler(CompilerBase, abstract.CxxCompiler):
  """Compiles C++ sources using Clang."""

  def __init__(self, **kwargs):
    super(CxxCompiler, self).__init__(**kwargs)

  def GetCommand(self, path, extra_flags, flags):
    return '{0} -x c++ -MMD -MF $out.d {1} {2} -c $in -o $out'.format(
        path, extra_flags, flags)

  def GetDescription(self):
    return 'CXX $out'

  def GetFlags(self, defines, include_dirs, cflags):
    define_flags = ['-D{0}'.format(define) for define in defines]
    include_dir_flags = [
        '-I{0}'.format(include_dir) for include_dir in include_dirs
    ]
    return define_flags + include_dir_flags + cflags


class AssemblerWithCPreprocessor(CompilerBase,
                                 abstract.AssemblerWithCPreprocessor):
  """Compiles assembler sources that contain C preprocessor directives."""

  def __init__(self, **kwargs):
    super(AssemblerWithCPreprocessor, self).__init__(**kwargs)

  def GetCommand(self, path, extra_flags, flags):
    return ('{0} -x assembler-with-cpp -MMD -MF $out.d {1} {2} -c $in -o $out'.
            format(path, extra_flags, flags))

  def GetDescription(self):
    return 'ASM $out'

  def GetFlags(self, defines, include_dirs, cflags):
    define_flags = ['-D{0}'.format(define) for define in defines]
    include_dir_flags = [
        '-I{0}'.format(include_dir) for include_dir in include_dirs
    ]
    return define_flags + include_dir_flags + cflags
