import os
import socket
import sys

from buildbot.plugins import reporters, util
from datetime import timedelta

import loadConfig
from events import Events


def load_password(name):
    if os.getenv(name):
        return os.getenv(name)
    try:
        passwords = json.load(open('passwords.json'))
        return passwords.get(name, None)
    except Exception as e:
        print('Error in finding {} in passwords.json'.format(name))
        return None


# This is work-around for Twisted having a small size limit for patches. See https://bugs.webkit.org/show_bug.cgi?id=198851#c5
from twisted.spread import banana
banana.SIZE_LIMIT = 100 * 1024 * 1024

# This is work-around for https://bugs.webkit.org/show_bug.cgi?id=222361
from buildbot.process.buildstep import BuildStep
BuildStep.warn_deprecated_if_oldstyle_subclass = lambda self, name: None

is_test_mode_enabled = os.getenv('BUILDBOT_PRODUCTION') is None

c = BuildmasterConfig = {}

c['www'] = dict(port='tcp:8010:interface=127.0.0.1', allowed_origins=["*"])
c['www']['custom_templates_dir'] = 'templates'

c['www']['ui_default_config'] = { 
    'Builders.show_workers_name': True,
    'Builders.buildFetchLimit': 1000,
    'Workers.showWorkerBuilders': True,
}
c['www']['change_hook_dialects'] = dict(
    github=dict(
        secret=load_password('GITHUB_HOOK_SECRET'),
        github_property_whitelist=[
            'github.number',
            'github.title',
            'github.head.ref',
            'github.base.sha',
            'github.head.repo.full_name',
        ],
    ),
)

if not is_test_mode_enabled:
    admin_username = os.getenv('EWS_ADMIN_USERNAME')
    admin_password = os.getenv('EWS_ADMIN_PASSWORD')
    if not admin_username or not admin_password:
        print('Environment variables for admin username/password not found. Please ensure these variables are set.')
        sys.exit(1)
    # See https://docs.buildbot.net/current/manual/configuration/www.html#example-configs
    authz = util.Authz(
        allowRules=[util.AnyControlEndpointMatcher(role="admin")],
        roleMatchers=[util.RolesFromEmails(admin=[admin_username])]
    )
    auth = util.UserPasswordAuth({admin_username: admin_password})
    c['www']['auth'] = auth
    c['www']['authz'] = authz

c['protocols'] = {'pb': {'port': 17000}}

c['projectName'] = 'WebKit EWS'
c['projectURL'] = 'https://ews-build.webkit.org/'

if is_test_mode_enabled:
    c['buildbotURL'] = 'http://localhost:8010/'
    c['db_url'] = 'sqlite:///state.sqlite?serialize_access=1'
else:
    c['buildbotURL'] = 'https://ews-build.webkit.org/'
    db_url = os.getenv('DB_URL', None)
    db_name = os.getenv('DB_NAME', None)
    db_username = os.getenv('DB_USERNAME', None)
    db_password = os.getenv('DB_PASSWORD', None)
    if None in [db_url, db_name, db_username, db_password]:
        print('Environment variables for DB not found. Please ensure these variables are set.')
        sys.exit(1)
    # See https://docs.buildbot.net/1.7.0/manual/configuration/global.html#database-specification
    c['db_url'] = 'postgresql://{}:{}@{}/{}'.format(db_username, db_password, db_url, db_name)
    # configure a janitor to delete old logs
    c['configurators'] = [util.JanitorConfigurator(logHorizon=timedelta(weeks=52), hour='1', dayOfWeek='*')]

c['logCompressionMethod'] = 'lz4'
c['buildbotNetUsageData'] = None

loadConfig.loadBuilderConfig(c, is_test_mode_enabled=is_test_mode_enabled)

mail_notifier = reporters.MailNotifier(
    fromaddr='ews-build@webkit.org',
    sendToInterestedUsers=False,
    extraRecipients=['webkit-ews-bot-watchers@group.apple.com'],
    mode=('exception'),
    addPatch=False)

if not is_test_mode_enabled:
    hostname =  socket.gethostname().strip()
    event_reporter = Events(master_hostname=hostname, type_prefix='ews')
    c['services'] = [event_reporter, mail_notifier]
