# Copyright 2018 The Tulsi 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.
#
#
# Generated by Tulsi to resolve flags during builds.


def _StandardizeTargetLabel(label):
  """Convert labels of form //dir/target to //dir/target:target."""
  if label is None:
    return label
  tokens = label.rsplit('/', 1)
  if len(tokens) <= 1:
    return label

  target_base = tokens[0]
  target = tokens[1]

  if '...' in target or ':' in target:
    return label
  return label + ':' + target


class BazelFlags(object):
  """Represents Bazel flags."""

  def __init__(self, startup = [], build = []):
    self.startup = startup
    self.build = build


class BazelFlagsSet(object):
  """Represents a set of Bazel flags which can vary by compilation mode."""

  def __init__(self, debug = None, release = None, flags = None):
    if debug is None:
      debug = flags or BazelFlags()
    if release is None:
      release = flags or BazelFlags()

    self.debug = debug
    self.release = release

  def flags(self, is_debug):
    """Returns the proper flags (either debug or release)."""
    return self.debug if is_debug else self.release


class BazelBuildSettings(object):
  """Represents a Tulsi project's Bazel settings."""

  def __init__(self, bazel, bazelExecRoot,
               defaultPlatformConfigId, platformConfigFlags,
               swiftTargets,
               cacheAffecting, cacheSafe,
               swiftOnly, nonSwiftOnly,
               swiftFeatures, nonSwiftFeatures,
               projDefault, projTargetMap):
    self.bazel = bazel
    self.bazelExecRoot = bazelExecRoot
    self.defaultPlatformConfigId = defaultPlatformConfigId
    self.platformConfigFlags = platformConfigFlags
    self.swiftTargets = swiftTargets
    self.cacheAffecting = cacheAffecting
    self.cacheSafe = cacheSafe
    self.swiftOnly = swiftOnly
    self.nonSwiftOnly = nonSwiftOnly
    self.swiftFeatures = swiftFeatures
    self.nonSwiftFeatures = nonSwiftFeatures
    self.projDefault = projDefault
    self.projTargetMap = projTargetMap

  def features_for_target(self, target, is_swift_override=None):
    """Returns an array of enabled features for the given target."""

    target = _StandardizeTargetLabel(target)
    is_swift = target in self.swiftTargets
    if is_swift_override is not None:
      is_swift = is_swift_override

    return self.swiftFeatures if is_swift else self.nonSwiftFeatures

  def flags_for_target(self, target, is_debug,
                       config, is_swift_override=None):
    """Returns (bazel, startup flags, build flags) for the given target."""

    target = _StandardizeTargetLabel(target)
    target_flag_set = self.projTargetMap.get(target)
    if not target_flag_set:
      target_flag_set = self.projDefault

    is_swift = target in self.swiftTargets
    if is_swift_override is not None:
      is_swift = is_swift_override
    lang = self.swiftOnly if is_swift else self.nonSwiftOnly

    config_flags = self.platformConfigFlags[config]
    cache_affecting = self.cacheAffecting.flags(is_debug)
    cache_safe = self.cacheSafe.flags(is_debug)
    target = target_flag_set.flags(is_debug)
    lang = lang.flags(is_debug)

    startupFlags = []
    startupFlags.extend(target.startup)
    startupFlags.extend(cache_safe.startup)
    startupFlags.extend(cache_affecting.startup)
    startupFlags.extend(lang.startup)

    buildFlags = []
    buildFlags.extend(target.build)
    buildFlags.extend(config_flags)
    buildFlags.extend(cache_safe.build)
    buildFlags.extend(cache_affecting.build)
    buildFlags.extend(lang.build)

    return (self.bazel, startupFlags, buildFlags)

# Default value in case the template does not behave as expected.
BUILD_SETTINGS = None

# <template>

