# The Craftr build system
# Copyright (C) 2016  Niklas Rosenstein
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

if options.toolkit.startswith('msvc') or options.toolkit.startswith('clang-cl'):
  module = 'craftr.lang.cxx.msvc'
elif options.toolkit.startswith('llvm') or options.toolkit.startswith('gcc') \
    or options.toolkit.startswith('clang'):
  module = 'craftr.lang.cxx.common'
elif options.toolkit.startswith('craftr:'):
  module = options.toolkit[7:]
elif options.toolkit:
  raise EnvironmentError('unsupported toolkit: {}'.format(options.toolkit))
elif platform.name == 'win':
  module = 'craftr.lang.cxx.msvc'
else:
  module = 'craftr.lang.cxx.common'

session.options.setdefault('{}.toolkit'.format(module), options.toolkit)

logger.info('Loading CXX Toolkit "{0}" (with {0}.toolkit="{1}")'.format(module, options.toolkit))
with logger.indent():
  cxc = load(module).cxc
  logger.info('cxc.name="{}"'.format(cxc.name))
  logger.info('cxc.target_arch="{}"'.format(cxc.target_arch))
  logger.info('cxc.version="{}"'.format(cxc.version))

# High-level interface.
def compile_c(*args, name=None, **kwargs):
  return cxc.compile(*args, name=gtn(name, None), language='c', **kwargs)

def compile_cpp(*args, name=None, **kwargs):
  return cxc.compile(*args, name=gtn(name, None), language='c++', **kwargs)

def compile_asm(*args, name=None, **kwargs):
  return cxc.compile(*args, name=gtn(name, None), language='asm', **kwargs)

def library(*args, name=None, link_style='static', **kwargs):
  if link_style == 'static':
    target = cxc.staticlib(*args, name=gtn(name, None), **kwargs)
    target.metadata['link_target'] = target.metadata['staticlib_output']
  elif link_style == 'shared':
    target = cxc.link(*args, name=gtn(name, None), output_type='dll', **kwargs)
    target.metadata['link_target'] = target.metadata['dll_link_target']
  return target

def static_library(*args, name=None, **kwargs):
  return library(*args, name=gtn(name, None), link_style='static', **kwargs)

def shared_library(*args, name=None, **kwargs):
  return library(*args, name=gtn(name, None), link_style='shared', **kwargs)

def executable(*args, name=None, **kwargs):
  return cxc.link(*args, name=gtn(name, None), output_type='bin', **kwargs)

def extend_framework(framework, *targets):
  """
  When compiling C/C++ libraries from source, this function can be used to
  make it easier to embed the output library and implicit dependencies into
  the *framework*.
  """

  framework.setdefault('external_libs', [])
  framework.setdefault('implicit_deps', [])
  for target in targets:
    link_target = target.metadata.get('link_target')
    if link_target:
      framework['external_libs'].append(link_target)
    framework['implicit_deps'].append(target)

# Backwards compatibility.
def binary(*args, name=None, **kwargs):
  logger.warn('clang.lang.cxx:binary() is deprecated, use cxx.executable() instead')
  return executable(*args, name=gtn(name, None), **kwargs)

def c_compile(*args, name=None, **kwargs):
  logger.warn('craftr.lang.cxx:c_compile() is deprecated, use cxx.compile_c() instead')
  return compile_c(*args, name=gtn(name, None), **kwargs)

def cpp_compile(*args, name=None, **kwargs):
  logger.warn('craftr.lang.cxx:cpp_compile() is deprecated, use cxx.compile_cpp() instead')
  return compile_cpp(*args, name=gtn(name, None), **kwargs)

def cxx_binary(*args, name=None, **kwargs):
  logger.warn('craftr.lang.cxx:cxx_binary() is deprecated, use cxx.executable() instead')
  return executable(*args, name=gtn(name, None), **kwargs)

def cxx_library(*args, name=None, **kwargs):
  logger.warn('craftr.lang.cxx:cxx_library() is deprecated, use cxx.library() instead')
  return library(*args, name=gtn(name, None), **kwargs)

def cxx_extend_framework(*args, **kwargs):
  logger.warn('craftr.lang.cxx:cxx_extend_framework() is deprecated, use cxx.extend_library() instead')
  return extend_framework(*args, **kwargs)

__all__ = ['cxc', 'c_compile', 'cpp_compile', 'cxx_library', 'cxx_binary', 'cxx_extend_framework']
