# Copyright (C) 2011 Google Inc. All rights reserved.
# Copyright (C) 2013 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import re


# In this dictionary, each item stores:
# * port_name -- a fully qualified port name
# * is_debug -- whether we are using a debug build
# * move_overwritten_baselines_to -- (optional) list of platform directories that we will copy an existing
#      baseline to before pulling down a new baseline during rebaselining. This is useful
#      for bringing up a new port, for example when adding a Lion was the most recent Mac version and
#      we wanted to bring up Mountain Lion, we would want to copy an existing baseline in platform/mac
#      to platform/mac-mountainlion before updating the platform/mac entry.
# * rebaseline_override_dir -- (optional) directory to put baselines in instead of where you would normally put them.
#      This is useful when we don't have bots that cover particular configurations; so, e.g., you might
#      support mac-mountainlion but not have a mac-mountainlion bot yet, so you'd want to put the mac-lion
#      results into platform/mac temporarily.

_exact_matches = {
    # These builders are on build.webkit.org.

    "Apple Yosemite Release WK1 (Tests)": {"port_name": "mac-yosemite", "is_debug": False},
    "Apple Yosemite Debug WK1 (Tests)": {"port_name": "mac-yosemite", "is_debug": True},
    "Apple Yosemite Release WK2 (Tests)": {"port_name": "mac-yosemite-wk2", "is_debug": False},
    "Apple Yosemite Debug WK2 (Tests)": {"port_name": "mac-yosemite-wk2", "is_debug": True},

    "Apple Mavericks Release WK1 (Tests)": {"port_name": "mac-mavericks", "is_debug": False},
    "Apple Mavericks Debug WK1 (Tests)": {"port_name": "mac-mavericks", "is_debug": True},
    "Apple Mavericks Release WK2 (Tests)": {"port_name": "mac-mavericks-wk2", "is_debug": False},
    "Apple Mavericks Debug WK2 (Tests)": {"port_name": "mac-mavericks-wk2", "is_debug": True},

    "Apple MountainLion Release WK1 (Tests)": {"port_name": "mac-mountainlion", "is_debug": False},
    "Apple MountainLion Debug WK1 (Tests)": {"port_name": "mac-mountainlion", "is_debug": True},
    "Apple MountainLion Release WK2 (Tests)": {"port_name": "mac-mountainlion-wk2", "is_debug": False},
    "Apple MountainLion Debug WK2 (Tests)": {"port_name": "mac-mountainlion-wk2", "is_debug": True},

    "Apple Lion Release WK1 (Tests)": {"port_name": "mac-lion", "is_debug": False},
    "Apple Lion Debug WK1 (Tests)": {"port_name": "mac-lion", "is_debug": True},
    "Apple Lion Release WK2 (Tests)": {"port_name": "mac-lion-wk2", "is_debug": False},
    "Apple Lion Debug WK2 (Tests)": {"port_name": "mac-lion-wk2", "is_debug": True},

    "Apple Win XP Debug (Tests)": {"port_name": "win-xp", "is_debug": True},
    # FIXME: Remove rebaseline_override_dir once there is an Apple buildbot that corresponds to platform/win.
    "Apple Win 7 Release (Tests)": {"port_name": "win-7sp0", "is_debug": False, "rebaseline_override_dir": "win"},

    "GTK Linux 32-bit Release": {"port_name": "gtk-wk2", "is_debug": False},
    "GTK Linux 64-bit Debug (Tests)": {"port_name": "gtk-wk2", "is_debug": True},
    "GTK Linux 64-bit Release (Tests)": {"port_name": "gtk-wk2", "is_debug": False},
    "GTK Linux 64-bit Release Wayland (Tests)": {"port_name": "gtk-wayland", "is_debug": False},
    "WPE Linux 64-bit Debug (Tests)": {"port_name": "wpe", "is_debug": True},
    "WPE Linux 64-bit Release (Tests)": {"port_name": "wpe", "is_debug": False},
}


_fuzzy_matches = {
    # These builders are on build.webkit.org.
    r"SnowLeopard": "mac-snowleopard",
    r"Apple Lion": "mac-lion",
    r"Windows": "win",
    r"GTK": "gtk",
    r"WPE": "wpe",
}


_ports_without_builders = [
    r"ios-simulator-11",
    r"ios-simulator-11-wk2",
]


def builder_path_from_name(builder_name):
    return re.sub(r'[\s().]', '_', builder_name)


def all_builder_names():
    return sorted(set(_exact_matches.keys()))


def all_port_names():
    return sorted(set(list(map(lambda x: x["port_name"], _exact_matches.values())) + _ports_without_builders))


def rebaseline_override_dir(builder_name):
    return _exact_matches[builder_name].get("rebaseline_override_dir", None)


def move_overwritten_baselines_to(builder_name):
    return _exact_matches[builder_name].get("move_overwritten_baselines_to", [])


def port_name_for_builder_name(builder_name):
    if builder_name in _exact_matches:
        return _exact_matches[builder_name]["port_name"]

    for regexp, port_name in _fuzzy_matches.items():
        if re.match(regexp, builder_name):
            return port_name


def builder_name_for_port_name(target_port_name):
    debug_builder_name = None
    for builder_name, builder_info in _exact_matches.items():
        if builder_info['port_name'] == target_port_name:
            if builder_info['is_debug']:
                debug_builder_name = builder_name
            else:
                return builder_name
    return debug_builder_name


def builder_path_for_port_name(port_name):
    builder_path_from_name(builder_name_for_port_name(port_name))
