package ru.yandex.autotests.directapi.model.api5.general;

import java.util.Map;

import com.google.common.collect.ImmutableMap;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import ru.yandex.autotests.direct.utils.DirectUtilsException;
import ru.yandex.autotests.direct.utils.config.DirectTestRunProperties;
import ru.yandex.autotests.direct.utils.textresource.ITextResource;
import ru.yandex.autotests.direct.utils.textresource.TextResourceFormatter;
import ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorDetails;
import ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage;
import ru.yandex.autotests.directapi.exceptions.DirectAPIException;

import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.AD_HAS_ALREADY_ARCHIVED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.AD_HAS_ALREADY_RESUMED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.AD_HAS_ALREADY_SUSPENDED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.AD_NOT_ARCHIVED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.ARCHIEVED_OBJECT_EDIT_NOT_ALLOWED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.AUTHORIZATION_ERROR;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.AUTOTARGETING_ALREADY_SUSPENDED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.AUTOTARGETING_HAS_NOT_BEEN_STOPPED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.BID_CAN_NOT_CHANGED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.BID_WILL_NOT_APPLIED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.COULD_NOT_ARCHIVE_OBJECT;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.COULD_NOT_UNARCHIVE_OBJECT;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.DAILY_BUDGET_IS_RESET;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.ELEMENT_CANT_PRESENT_IN_LIST_MORE_THAN_ONE_TIME;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.FIELD_NOT_MATCH_STRATEGY;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.FIELD_NOT_PASSED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.FIELD_SET_INCORRECTLY;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.GROUP_CONTAIN_OBJECTS;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.GROUP_NAME_CANNOT_BE_EMPTY;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.IMPRESSIONS_ARE_RESTRICTED_IN_SEVERAL_REGIONS;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.INCOMPATIBLE_OPERATIONS_IN_ONE_REQUEST;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.INCONSISTENT_OBJECT_STATE;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.INCORRECT_USE_OF_NEGATIVE_KEYWORDS;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.INCORRECT_USE_OF_STOPWORD;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.INVALID_ACTION;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.INVALID_FORMAT;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.INVALID_GEOTARGETING;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.INVALID_GEO_DATA_TO_DISPLAY_A_MAP;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.INVALID_OBJECT_STATUS;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.INVALID_REQUEST;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.INVALID_REQUEST_PARAMETERS;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.INVALID_TRACKING_URL;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.INVALID_USE_OF_FIELD;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.KEYWORD_ALREADY_SUSPENDED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.KEYWORD_CONTAINS_TOO_MANY_WORDS;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.KEYWORD_DUPLICATES;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.KEYWORD_HAS_NOT_BEEN_STOPPED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.KEYWORD_LENGTH_EXCEEDED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.KEYWORD_MINUS_WORD_LENGTH_EXCEEDED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.KEYWORD_NOT_FOUND;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.KEYWORD_WAS_CREATED_USING_UPDATE;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.LANGUAGE_DOESNT_MATCH_GEOTARGETING;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.LIMIT_ACCESS;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.MANDATORY_FIELD;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.MAXIMUM_LENGTH_EXCEEDED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.MAXIMUM_NUMBER_OF_OBJECTS_REACHED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.MAX_FILE_SIZE_EXCEEDED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.MORE_THEN_ONE_FIELD_PASSED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.NAME_LENGTH_CANNOT_BE_MORE_THAN_255;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.NEGATIVE_KEYWORD_CANNOT_BE_PHRASE;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.NOT_ENOUGH_RIGHTS;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.NOT_POSSIBLE_TO_DELETE_OBJECT;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.NOT_POSSIBLE_TO_PAUSE_IMPRESSIONS;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.NOT_SUPPORTED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.NO_EFFECT;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.NO_ONE_OF_REQUIRED_FIELDS;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.NO_ONE_OF_REQUIRED_PARAMETERS;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.NUMBER_OF_PERMITED_ELEMENTS_EXCEEDED_OR_EQUALS_ZERO;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.OBJECTS_ALREADY_LINKED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.OBJECTS_NOT_LINKED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.OBJECT_ALREADY_ARCHIVED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.OBJECT_ALREADY_SUSPENDED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.OBJECT_CANNOT_BE_MORE_THAN_ONCE_IN_REQUEST;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.OBJECT_IS_MARKED_AS_DELETED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.OBJECT_IS_PRESENTED_MORE_THAN_ONCE_IN_REQUEST;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.OBJECT_NOT_ARCHIVED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.OBJECT_NOT_FOUND;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.OBJECT_NOT_SUSPENDED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.OBJECT_WITH_SUCH_PARAMS_ALREADY_EXISTS;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.OPERATION_NOT_FOUND;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.PARAM_WILL_NOT_BE_CHANGED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.PRIORITY_WILL_NOT_CHANGED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.PUT_MORE_THAN_ONE_PARAMETER;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.REGION_DOESNT_MATCH_ADS_TEXT;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.RELEVANT_KEYWORDS_DISABLED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.REPEATING_ELEMENT;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.SETTING_WILL_NOT_BE_CHANGED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.SET_EMPTY_VALUE;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.SITELINKS_DUPLICATES;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.SITELINKS_SET_USED_AND_CANT_BE_DELETED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.TRACKING_URL_DOESNT_CONTAIN_LOGID;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.UNABLE_DELETE_OBJECT;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.UNSUPPORTED_APPLICATION_STORE;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.USES_INADMISSIBLE_CHARACTERS;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.VCARD_DUPLICATES;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.WEBPAGE_NOT_SUSPENDED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.WEBPAGE_SUSPENDED;
import static ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorMessage.WRONG_OBJECT_TYPE;

/**
 * Created by chicos on 24.07.14.
 */
public class Notification extends ExceptionNotificationMap {
    private static Logger log = LogManager.getLogger(Notification.class);

    public Notification(int code) {
        this(code, (Api5ErrorDetails) null, (Object) null);
    }

    public Notification(int code, Api5ErrorDetails details) {
        this(null, code, details);
    }

    public Notification(String locale, int code, Api5ErrorDetails details) {
        this(locale, code, details, (Object) null);
    }

    public Notification(int code, ITextResource details, Object... params) {
        this(null, code, details, params);
    }

    public Notification(String locale, int code, ITextResource details, Object... params) {
        super();
        init(locale, code, NOTIFICATION_MESSAGES, details, params);
    }

    public void init(String locale,
            int code,
            Map<Integer, Api5ErrorMessage> messagesMap,
            ITextResource details,
            Object... params)
    {
        this.withCode(code);

        if (locale == null) {
            locale = DirectTestRunProperties.getInstance().getDirectAPILocale();
        }

        Api5ErrorMessage message = messagesMap.get(code);
        if (message == null) {
            throw new DirectAPIException("Отсутствует маппинг сообщения для ошибки с кодом " + code);
        }

        withMessageFromResource(message, locale, params);

        if (details == null) {
            this.withDetails(null);
        } else {
            try {
                TextResourceFormatter detailsFormatter = TextResourceFormatter.resource(details)
                        .args(params)
                        .locale(locale);
                this.withDetails(detailsFormatter.toString());
            } catch (DirectUtilsException noResourceKey) {
                log.error("Отсутствует описание деталей ошибки в ресурсах!");
                this.withDetails(details.toString());
            }
        }
    }

    public Notification withMessageFromResource(Api5ErrorMessage message, Object... params) {
        return withMessageFromResource(message, DirectTestRunProperties.getInstance().getDirectAPILocale(), params);
    }

    private Notification withMessageFromResource(Api5ErrorMessage message, String locale, Object... params) {
        try {
            TextResourceFormatter messageFormatter = TextResourceFormatter.resource(message)
                    .args(params)
                    .locale(locale);
            this.withMessage(messageFormatter.toString());
        } catch (DirectUtilsException noResourceKey) {
            log.error("Отсутствует сообщение для ошибки " + message + " в ресурсах!");
            this.withMessage(message.toString());
        }
        return this;
    }

    private static final Map<Integer, Api5ErrorMessage> NOTIFICATION_MESSAGES = ImmutableMap.<Integer, Api5ErrorMessage>builder()
            .put(54, NOT_ENOUGH_RIGHTS)
            .put(1002, AUTHORIZATION_ERROR)
            .put(1003, OPERATION_NOT_FOUND)
            .put(1012, MORE_THEN_ONE_FIELD_PASSED)
            .put(1013, FIELD_NOT_PASSED)
            .put(1014, ARCHIEVED_OBJECT_EDIT_NOT_ALLOWED)
            .put(3500, NOT_SUPPORTED)
            .put(3600, LIMIT_ACCESS)
            .put(4000, INVALID_REQUEST_PARAMETERS)
            .put(4003, NO_ONE_OF_REQUIRED_PARAMETERS)
            .put(4004, PUT_MORE_THAN_ONE_PARAMETER)
            .put(4006, INCOMPATIBLE_OPERATIONS_IN_ONE_REQUEST)
            .put(5000, MANDATORY_FIELD)
            .put(5001, MAXIMUM_LENGTH_EXCEEDED)
            .put(5002, USES_INADMISSIBLE_CHARACTERS)
            .put(5003, SET_EMPTY_VALUE)
            .put(5004, INVALID_FORMAT)
            .put(5005, FIELD_SET_INCORRECTLY)
            .put(5006, INVALID_USE_OF_FIELD)
            .put(5007, REPEATING_ELEMENT)
            .put(5008, NO_ONE_OF_REQUIRED_FIELDS)
            .put(5009, MORE_THEN_ONE_FIELD_PASSED)
            .put(5010, MAX_FILE_SIZE_EXCEEDED)
            .put(5120, INVALID_GEOTARGETING)
            .put(5140, KEYWORD_CONTAINS_TOO_MANY_WORDS)
            .put(5141, INCORRECT_USE_OF_STOPWORD)
            .put(5142, KEYWORD_LENGTH_EXCEEDED)
            .put(5160, NEGATIVE_KEYWORD_CANNOT_BE_PHRASE)
            .put(5161, INCORRECT_USE_OF_NEGATIVE_KEYWORDS)
            .put(5162, KEYWORD_MINUS_WORD_LENGTH_EXCEEDED)
            .put(5180, UNSUPPORTED_APPLICATION_STORE)
            .put(6000, INCONSISTENT_OBJECT_STATE)
            .put(6001, WRONG_OBJECT_TYPE)
            .put(6100, REGION_DOESNT_MATCH_ADS_TEXT)
            .put(6101, LANGUAGE_DOESNT_MATCH_GEOTARGETING)
            .put(7000, NUMBER_OF_PERMITED_ELEMENTS_EXCEEDED_OR_EQUALS_ZERO)
            .put(7001, MAXIMUM_NUMBER_OF_OBJECTS_REACHED)
            .put(7002, INVALID_TRACKING_URL)
            .put(8300, INVALID_OBJECT_STATUS)
            .put(8301, UNABLE_DELETE_OBJECT)
            .put(8302, NOT_POSSIBLE_TO_PAUSE_IMPRESSIONS)
            .put(8303, COULD_NOT_ARCHIVE_OBJECT)
            .put(8304, COULD_NOT_UNARCHIVE_OBJECT)
            .put(8305, INVALID_ACTION)
            .put(8000, INVALID_REQUEST)
            .put(8800, OBJECT_NOT_FOUND)
            .put(9600, FIELD_NOT_MATCH_STRATEGY)
            .put(9601, BID_CAN_NOT_CHANGED)
            .put(9800, OBJECT_CANNOT_BE_MORE_THAN_ONCE_IN_REQUEST)
            .put(9801, OBJECT_WITH_SUCH_PARAMS_ALREADY_EXISTS)
            .put(9802, ELEMENT_CANT_PRESENT_IN_LIST_MORE_THAN_ONE_TIME)
            .put(10000, OBJECT_IS_PRESENTED_MORE_THAN_ONCE_IN_REQUEST)
            .put(10120, SITELINKS_DUPLICATES)
            .put(10140, KEYWORD_DUPLICATES)
            .put(10141, KEYWORD_WAS_CREATED_USING_UPDATE)
            .put(10160, BID_WILL_NOT_APPLIED)
            .put(10161, PRIORITY_WILL_NOT_CHANGED)
            .put(10162, DAILY_BUDGET_IS_RESET)
            .put(10164, OBJECT_WITH_SUCH_PARAMS_ALREADY_EXISTS)
            .put(10172, IMPRESSIONS_ARE_RESTRICTED_IN_SEVERAL_REGIONS)
            .put(10200, AD_HAS_ALREADY_SUSPENDED)
            .put(10201, AD_HAS_ALREADY_RESUMED)
            .put(10202, AD_HAS_ALREADY_ARCHIVED)
            .put(10203, AD_NOT_ARCHIVED)
            .put(10240, KEYWORD_ALREADY_SUSPENDED)
            .put(10241, KEYWORD_HAS_NOT_BEEN_STOPPED)
            .put(10244, AUTOTARGETING_ALREADY_SUSPENDED)
            .put(10245, AUTOTARGETING_HAS_NOT_BEEN_STOPPED)
            .put(102002, GROUP_NAME_CANNOT_BE_EMPTY)
            .put(102003, NAME_LENGTH_CANNOT_BE_MORE_THAN_255)
            .put(102007, GROUP_CONTAIN_OBJECTS)
            .put(10100, VCARD_DUPLICATES)
            .put(10020, OBJECT_ALREADY_SUSPENDED)
            .put(10021, OBJECT_NOT_SUSPENDED)
            .put(10022, OBJECT_ALREADY_ARCHIVED)
            .put(10023, OBJECT_NOT_ARCHIVED)
            .put(10025, OBJECT_IS_MARKED_AS_DELETED)
            .put(10030, NO_EFFECT)
            .put(10035, INVALID_USE_OF_FIELD)
            .put(10163, SETTING_WILL_NOT_BE_CHANGED)
            .put(10165, PARAM_WILL_NOT_BE_CHANGED)
            .put(10170, OBJECTS_ALREADY_LINKED)
            .put(10171, OBJECTS_NOT_LINKED)
            .put(10173, RELEVANT_KEYWORDS_DISABLED)
            .put(10242, WEBPAGE_SUSPENDED)
            .put(10243, WEBPAGE_NOT_SUSPENDED)
            .put(10250, TRACKING_URL_DOESNT_CONTAIN_LOGID)
            .put(107002, SITELINKS_SET_USED_AND_CANT_BE_DELETED)
            .put(171004, KEYWORD_NOT_FOUND)
            .put(209001, INVALID_GEO_DATA_TO_DISPLAY_A_MAP)
            .put(1000115, NOT_POSSIBLE_TO_DELETE_OBJECT)
            .build();
}
