import ldclient
import logging

from ldclient.config import Config, HTTPConfig
from ldclient.integrations import Files

from django.conf import settings
from label_studio.core.utils.params import get_bool_env, get_all_env_with_prefix
from label_studio.core.utils.io import find_file

logger = logging.getLogger(__name__)


if settings.FEATURE_FLAGS_FROM_FILE:
    # Feature flags from file
    if not settings.FEATURE_FLAGS_FILE:
        raise ValueError('When "FEATURE_FLAGS_FROM_FILE" is set, you have to specify a valid path for feature flags file, e.g.'
                         'FEATURE_FLAGS_FILE=my_flags.yml')
    feature_flags_file = find_file(settings.FEATURE_FLAGS_FILE)
    logger.info(f'Read flags from file {feature_flags_file}')
    data_source = Files.new_data_source(paths=[feature_flags_file])
    config = Config(
        sdk_key=settings.FEATURE_FLAGS_API_KEY or 'whatever',
        update_processor_class=data_source,
        send_events=False)
    ldclient.set_config(config)
    client = ldclient.get()
elif settings.FEATURE_FLAGS_OFFLINE:
    # On-prem usage, without feature flags file
    ldclient.set_config(Config(settings.FEATURE_FLAGS_API_KEY or 'whatever', offline=True))
    client = ldclient.get()
else:
    # Production usage
    ldclient.set_config(Config(settings.FEATURE_FLAGS_API_KEY, http=HTTPConfig(connect_timeout=5)))
    client = ldclient.get()


def _get_user_repr(user):
    """Turn user object into dict with required properties"""
    from users.serializers import UserSerializer
    if user.is_anonymous:
        return {'key': str(user)}
    user_data = UserSerializer(user).data
    user_data['key'] = user_data['email']
    logger.debug(f'Read user properties: {user_data}')
    return user_data


def flag_set(feature_flag, user):
    """Use this method to check whether this flag is set ON to the current user, to split the logic on backend
    For example,
    ```
    if flag_set('ff-dev-123-some-fixed-issue-231221-short', user):
        run_new_code()
    else:
        run_old_code()
    ```
    """
    user_dict = _get_user_repr(user)
    default_value = get_bool_env(feature_flag, False)
    is_on = client.variation(feature_flag, user_dict, default_value)
    return is_on


def all_flags(user):
    """Return the output of this method in API response, to bootstrap client-side flags.
    More on https://docs.launchdarkly.com/sdk/features/bootstrapping#javascript
    """
    user_dict = _get_user_repr(user)
    state = client.all_flags_state(user_dict)
    flags = state.to_json_dict()
    env_ff = get_all_env_with_prefix('ff_')
    for env_flag_name, env_flag_on in env_ff.items():
        if env_flag_name not in flags and env_flag_on:
            flags[env_flag_name] = True
    logger.debug(f'Requested all active feature flags: {flags}')
    return flags
