<reponame>Solida-Software/Solida-Software-Embedded-Base
def _get_last_element(s):
    res = []
    index = s.rfind("/")
    if index > 0:
        element = s[index + 1:]
        path = s[:index]
    else:
        element = s
        path = ""
    return path, element

def _create_constraint(ctx, constraint):
    path = "{}/BUILD.bazel".format(constraint)
    _, name = _get_last_element(constraint)
    ctx.file(
        path,
        content = """
constraint_setting(
    name = "_setting",
    visibility=["//visibility:public"],
)

constraint_value(
    name = "{name}",
    visibility=["//visibility:public"],
    constraint_setting = ":_setting",
)

config_setting(
    name = "config_setting",
    visibility=["//visibility:public"],
    constraint_values = [
        ":{name}",
    ],
)

alias(name = "c",      actual = ":config_setting", visibility=["//visibility:public"])
alias(name = "conf",   actual = ":config_setting", visibility=["//visibility:public"])
alias(name = "config", actual = ":config_setting", visibility=["//visibility:public"])
""".format(name = name)
    )

def _create_platform(ctx, platform):
    path = "{}/BUILD.bazel".format(platform[0])
    ctx.file(
        path,
        content = """
platform(
    name = "{platform}",
    visibility=["//visibility:public"],
    constraint_values = {constraints}
)
""".format(platform = platform[0], constraints = str(platform[1]))
    )

def _create_platform_bzl(ctx):
    ctx.file(
        "constraints.bzl",
        content = """def get_constraints_list():
    return {constraints}""".format(constraints = ctx.attr.constraints)
    )

    ctx.file(
        "platform.bzl",
        content = """
load(":constraints.bzl", "get_constraints_list")

def get_constraints():
    constraints = []

    for constraint in get_constraints_list():
        res = select({
            "@SSEB_platforms//" + constraint + ":config": [constraint],
            "//conditions:default": [],
        })
        constraints += res

    return constraints""")

def _create_toolchain_constraints(ctx):
    ctx.file(
        "toolchain/compiler/BUILD.bazel",
        content = """
constraint_setting(
    name = "compiler",
    visibility=["//visibility:public"],
)
"""
    )

    ctx.file(
        "toolchain/compiler/avr8/BUILD.bazel",
        content = """
constraint_value(
    name = "avr8",
    visibility=["//visibility:public"],
    constraint_setting = "//toolchain/compiler",
)

config_setting(
    name = "config_setting",
    visibility=["//visibility:public"],
    constraint_values = [":avr8"],
)

alias(name = "c",      actual = ":config_setting", visibility=["//visibility:public"])
alias(name = "conf",   actual = ":config_setting", visibility=["//visibility:public"])
alias(name = "config", actual = ":config_setting", visibility=["//visibility:public"])
"""
    )

def _platforms_impl(ctx):
    ctx.file(
        "WORKSPACE", 
        content = """workspace(name = "{name}")
""".format(name = ctx.name))

    ctx.file(
        "BUILD.bazel", 
        content = "")

    _create_toolchain_constraints(ctx)

    _create_platform_bzl(ctx)

    for constraint in ctx.attr.constraints:
        _create_constraint(ctx, constraint)

    for platform in ctx.attr.platforms.items():
        _create_platform(ctx, platform)

platforms = repository_rule(
    implementation = _platforms_impl,
    local = True,
    attrs = {
        "constraints": attr.string_list(),
        "platforms": attr.string_list_dict()
    }
)
def _get_last_element(s):
    res = []
    index = s.rfind("/")
    if index > 0:
        element = s[index + 1:]
        path = s[:index]
    else:
        element = s
        path = ""
    return path, element

def _create_constraint(ctx, constraint):
    path = "{}/BUILD.bazel".format(constraint)
    _, name = _get_last_element(constraint)
    ctx.file(
        path,
        content = """
constraint_setting(
    name = "_setting",
    visibility=["//visibility:public"],
)

constraint_value(
    name = "{name}",
    visibility=["//visibility:public"],
    constraint_setting = ":_setting",
)

config_setting(
    name = "config_setting",
    visibility=["//visibility:public"],
    constraint_values = [
        ":{name}",
    ],
)

alias(name = "c",      actual = ":config_setting", visibility=["//visibility:public"])
alias(name = "conf",   actual = ":config_setting", visibility=["//visibility:public"])
alias(name = "config", actual = ":config_setting", visibility=["//visibility:public"])
""".format(name = name)
    )

def _create_platform(ctx, platform):
    path = "{}/BUILD.bazel".format(platform[0])
    ctx.file(
        path,
        content = """
platform(
    name = "{platform}",
    visibility=["//visibility:public"],
    constraint_values = {constraints}
)
""".format(platform = platform[0], constraints = str(platform[1]))
    )

def _create_platform_bzl(ctx):
    ctx.file(
        "constraints.bzl",
        content = """def get_constraints_list():
    return {constraints}""".format(constraints = ctx.attr.constraints)
    )

    ctx.file(
        "platform.bzl",
        content = """
load(":constraints.bzl", "get_constraints_list")

def get_constraints():
    constraints = []

    for constraint in get_constraints_list():
        res = select({
            "@SSEB_platforms//" + constraint + ":config": [constraint],
            "//conditions:default": [],
        })
        constraints += res

    return constraints""")

def _create_toolchain_constraints(ctx):
    ctx.file(
        "toolchain/compiler/BUILD.bazel",
        content = """
constraint_setting(
    name = "compiler",
    visibility=["//visibility:public"],
)
"""
    )

    ctx.file(
        "toolchain/compiler/avr8/BUILD.bazel",
        content = """
constraint_value(
    name = "avr8",
    visibility=["//visibility:public"],
    constraint_setting = "//toolchain/compiler",
)

config_setting(
    name = "config_setting",
    visibility=["//visibility:public"],
    constraint_values = [":avr8"],
)

alias(name = "c",      actual = ":config_setting", visibility=["//visibility:public"])
alias(name = "conf",   actual = ":config_setting", visibility=["//visibility:public"])
alias(name = "config", actual = ":config_setting", visibility=["//visibility:public"])
"""
    )

def _platforms_impl(ctx):
    ctx.file(
        "WORKSPACE", 
        content = """workspace(name = "{name}")
""".format(name = ctx.name))

    ctx.file(
        "BUILD.bazel", 
        content = "")

    _create_toolchain_constraints(ctx)

    _create_platform_bzl(ctx)

    for constraint in ctx.attr.constraints:
        _create_constraint(ctx, constraint)

    for platform in ctx.attr.platforms.items():
        _create_platform(ctx, platform)

platforms = repository_rule(
    implementation = _platforms_impl,
    local = True,
    attrs = {
        "constraints": attr.string_list(),
        "platforms": attr.string_list_dict()
    }
)
constraint_setting(     name = "_setting",     visibility=["//visibility:public"], )  constraint_value(     name = "{name}",     visibility=["//visibility:public"],     constraint_setting = ":_setting", )  config_setting(     name = "config_setting",     visibility=["//visibility:public"],     constraint_values = [         ":{name}",     ], )  alias(name = "c",      actual = ":config_setting", visibility=["//visibility:public"]) alias(name = "conf",   actual = ":config_setting", visibility=["//visibility:public"]) alias(name = "config", actual = ":config_setting", visibility=["//visibility:public"]) platform(     name = "{platform}",     visibility=["//visibility:public"],     constraint_values = {constraints} ) def get_constraints_list():     return {constraints} load(":constraints.bzl", "get_constraints_list")  def get_constraints():     constraints = []      for constraint in get_constraints_list():         res = select({             "@SSEB_platforms//" + constraint + ":config": [constraint],             "//conditions:default": [],         })         constraints += res      return constraints constraint_setting(     name = "compiler",     visibility=["//visibility:public"], ) constraint_value(     name = "avr8",     visibility=["//visibility:public"],     constraint_setting = "//toolchain/compiler", )  config_setting(     name = "config_setting",     visibility=["//visibility:public"],     constraint_values = [":avr8"], )  alias(name = "c",      actual = ":config_setting", visibility=["//visibility:public"]) alias(name = "conf",   actual = ":config_setting", visibility=["//visibility:public"]) alias(name = "config", actual = ":config_setting", visibility=["//visibility:public"]) workspace(name = "{name}")