# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

# pylint: disable=line-too-long, too-many-locals, too-many-statements

import json
import time
import sys

from itertools import chain
from knack.log import get_logger
from knack.util import CLIError

from azure.appconfiguration import (ConfigurationSetting,
                                    ResourceReadOnlyError)
from azure.core import MatchConditions
from azure.cli.core.util import user_confirmation
from azure.core.exceptions import (HttpResponseError,
                                   ResourceNotFoundError,
                                   ResourceModifiedError)

from ._constants import (FeatureFlagConstants, KeyVaultConstants,
                         SearchFilterOptions, StatusCodes, ImportExportProfiles)
from ._models import (convert_configurationsetting_to_keyvalue,
                      convert_keyvalue_to_configurationsetting)
from ._utils import get_appconfig_data_client, prep_label_filter_for_url_encoding

from ._kv_helpers import (__compare_kvs_for_restore, __read_kv_from_file, __read_features_from_file,
                          __write_kv_and_features_to_file, __read_kv_from_config_store, __is_json_content_type,
                          __write_kv_and_features_to_config_store, __discard_features_from_retrieved_kv,
                          __read_kv_from_app_service, __write_kv_to_app_service, __print_restore_preview,
                          __serialize_kv_list_to_comparable_json_object, __print_preview,
                          __serialize_features_from_kv_list_to_comparable_json_object, __export_kvset_to_file,
                          __serialize_feature_list_to_comparable_json_object, __print_features_preview,
                          __import_kvset_from_file)
from .feature import list_feature

logger = get_logger(__name__)


def import_config(cmd,
                  source,
                  name=None,
                  connection_string=None,
                  label=None,
                  prefix="",  # prefix to add
                  yes=False,
                  skip_features=False,
                  content_type=None,
                  auth_mode="key",
                  endpoint=None,
                  # from-file parameters
                  path=None,
                  format_=None,
                  separator=None,
                  depth=None,
                  profile=ImportExportProfiles.DEFAULT,
                  # from-configstore parameters
                  src_name=None,
                  src_connection_string=None,
                  src_key=None,
                  src_label=None,
                  preserve_labels=False,
                  src_auth_mode="key",
                  src_endpoint=None,
                  # from-appservice parameters
                  appservice_account=None):
    src_features = []
    dest_features = []
    dest_kvs = []
    source = source.lower()
    profile = profile.lower()
    format_ = format_.lower() if format_ else None

    azconfig_client = get_appconfig_data_client(cmd, name, connection_string, auth_mode, endpoint)

    # fetch key values from source
    if source == 'file':
        if profile == ImportExportProfiles.KVSET:
            __import_kvset_from_file(client=azconfig_client, path=path, yes=yes)
            return
        if format_ and content_type:
            # JSON content type is only supported with JSON format.
            # Error out if user has provided JSON content type with any other format.
            if format_ != 'json' and __is_json_content_type(content_type):
                raise CLIError("Failed to import '{}' file format with '{}' content type. Please provide JSON file format to match your content type.".format(format_, content_type))

        if separator:
            # If separator is provided, use max depth by default unless depth is specified.
            depth = sys.maxsize if depth is None else int(depth)
        else:
            if depth and int(depth) != 1:
                logger.warning("Cannot flatten hierarchical data without a separator. --depth argument will be ignored.")
            depth = 1
        src_kvs = __read_kv_from_file(file_path=path,
                                      format_=format_,
                                      separator=separator,
                                      prefix_to_add=prefix,
                                      depth=depth,
                                      content_type=content_type)

        if not skip_features:
            # src_features is a list of KeyValue objects
            src_features = __read_features_from_file(file_path=path, format_=format_)

    elif source == 'appconfig':
        src_azconfig_client = get_appconfig_data_client(cmd, src_name, src_connection_string, src_auth_mode, src_endpoint)

        if label is not None and preserve_labels:
            raise CLIError("Import failed! Please provide only one of these arguments: '--label' or '--preserve-labels'. See 'az appconfig kv import -h' for examples.")
        if preserve_labels:
            # We need label to be the same as src_label for preview later.
            # This will have no effect on label while writing to config store
            # as we check preserve_labels again before labelling KVs.
            label = src_label

        src_kvs = __read_kv_from_config_store(src_azconfig_client,
                                              key=src_key,
                                              label=src_label if src_label else SearchFilterOptions.EMPTY_LABEL,
                                              prefix_to_add=prefix)
        # We need to separate KV from feature flags
        __discard_features_from_retrieved_kv(src_kvs)

        if not skip_features:
            # Get all Feature flags with matching label
            all_features = __read_kv_from_config_store(src_azconfig_client,
                                                       key=FeatureFlagConstants.FEATURE_FLAG_PREFIX + '*',
                                                       label=src_label if src_label else SearchFilterOptions.EMPTY_LABEL)
            for feature in all_features: