import furl
import threading

from django.utils import timezone

from website import mails
from website.models import PreprintProvider
from website.settings import DOMAIN, CAMPAIGN_REFRESH_THRESHOLD
from website.util.time import throttle_period_expired


mutex = threading.Lock()
CAMPAIGNS = None
CAMPAIGNS_LAST_REFRESHED = timezone.now()


def get_campaigns():

    global CAMPAIGNS
    global CAMPAIGNS_LAST_REFRESHED

    if not CAMPAIGNS or (not mutex.locked() and throttle_period_expired(CAMPAIGNS_LAST_REFRESHED, CAMPAIGN_REFRESH_THRESHOLD)):
        with mutex:
            # Native campaigns: PREREG and ERPC
            newest_campaigns = {
                'prereg': {
                    'system_tag': 'prereg_challenge_campaign',
                    'redirect_url': furl.furl(DOMAIN).add(path='prereg/').url,
                    'confirmation_email_template': mails.CONFIRM_EMAIL_PREREG,
                    'login_type': 'native',
                },
                'erpc': {
                    'system_tag': 'erp_challenge_campaign',
                    'redirect_url': furl.furl(DOMAIN).add(path='erpc/').url,
                    'confirmation_email_template': mails.CONFIRM_EMAIL_ERPC,
                    'login_type': 'native',
                },
            }

            # Institution Login
            newest_campaigns.update({
                'institution': {
                    'system_tag': 'institution_campaign',
                    'redirect_url': '',
                    'login_type': 'institution',
                },
            })

            # Proxy campaigns: Preprints, both OSF and branded ones
            preprint_providers = PreprintProvider.objects.all()
            for provider in preprint_providers:
                if provider._id == 'osf':
                    template = 'osf'
                    name = 'OSF'
                    url_path = 'preprints/'
                else:
                    template = 'branded'
                    name = provider.name
                    url_path = 'preprints/{}'.format(provider._id)
                campaign = '{}-preprints'.format(provider._id)
                system_tag = '{}_preprints'.format(provider._id)
                newest_campaigns.update({
                    campaign: {
                        'system_tag': system_tag,
                        'redirect_url': furl.furl(DOMAIN).add(path=url_path).url,
                        'confirmation_email_template': mails.CONFIRM_EMAIL_PREPRINTS(template, name),
                        'login_type': 'proxy',
                        'provider': name,
                    }
                })

            CAMPAIGNS = newest_campaigns
            CAMPAIGNS_LAST_REFRESHED = timezone.now()

    return CAMPAIGNS


def system_tag_for_campaign(campaign):
    campaigns = get_campaigns()
    if campaign in campaigns:
        return campaigns.get(campaign).get('system_tag')
    return None


def email_template_for_campaign(campaign):
    campaigns = get_campaigns()
    if campaign in campaigns:
        return campaigns.get(campaign).get('confirmation_email_template')
    return None


def campaign_for_user(user):
    campaigns = get_campaigns()
    for campaign, config in campaigns.items():
        if config.get('system_tag') in user.system_tags:
            return campaign
    return None


def is_institution_login(campaign):
    campaigns = get_campaigns()
    if campaign in campaigns:
        return campaigns.get(campaign).get('login_type') == 'institution'
    return None


def is_native_login(campaign):
    campaigns = get_campaigns()
    if campaign in campaigns:
        return campaigns.get(campaign).get('login_type') == 'native'
    return None


def is_proxy_login(campaign):
    campaigns = get_campaigns()
    if campaign in campaigns:
        return campaigns.get(campaign).get('login_type') == 'proxy'
    return None


def get_service_provider(campaign):
    campaigns = get_campaigns()
    if campaign in campaigns:
        return campaigns.get(campaign).get('provider')
    return None


def campaign_url_for(campaign):
    campaigns = get_campaigns()
    if campaign in campaigns:
        return campaigns.get(campaign).get('redirect_url')
    return None

@@ -89,23 +89,19 @@
 ls%0Afrom 
-website
+osf
 .models 
@@ -1890,16 +1890,56 @@
 rints/'%0A
+                    external_url = None%0A
         
@@ -2093,32 +2093,107 @@
 t(provider._id)%0A
+                    external_url = provider.get_provider_external_domain()%0A
                 
@@ -2506,24 +2506,78 @@
 _path).url,%0A
+                        'external_url': external_url,%0A
             
@@ -4243,32 +4243,150 @@
 _for(campaign):%0A
+    %22%22%22%0A    Return the campaign's URL on OSF domain.%0A%0A    :param campaign: the campaign%0A    :return: the url%0A    %22%22%22%0A%0A
     campaigns = 
@@ -4490,16 +4490,16 @@
 t_url')%0A
-
     retu
@@ -4490,24 +4490,835 @@
 t_url')%0A    return None%0A
+%0A%0Adef external_campaign_url_for(campaign):%0A    %22%22%22%0A    Return the campaign's URL on Non-OSF domain, which is available for phase 2 branded preprints only.%0A%0A    :param campaign: the campaign%0A    :return: the external url if the campaign is hosted on Non-OSF domain, None otherwise%0A    %22%22%22%0A%0A    campaigns = get_campaigns()%0A    if campaign in campaigns:%0A        return campaigns.get(campaign).get('external_url')%0A    return None%0A%0A%0Adef get_external_domains():%0A    %22%22%22%0A    Return a list of trusted external domains for all eligible campaigns.%0A    %22%22%22%0A%0A    campaigns = get_campaigns()%0A    external_domains = %5B%5D%0A    for campaign, config in campaigns.items():%0A        external_url = config.get('external_url', None)%0A        if external_url:%0A            external_domains.append(external_url)%0A    return external_domains%0A

Add back accidentally removed code from commits: - 2efe814b1e6251883178deb157062b1dbae9e725 - 81dbc34ac71bdb4f0bef64e31d0a38962d5dcedd