package ru.yandex.autotests.directapi.model.campaigns;

import java.util.Date;

import org.joda.time.DateTime;

import ru.yandex.autotests.direct.utils.model.ModelBeanMap;
import ru.yandex.autotests.direct.utils.money.Currency;
import ru.yandex.autotests.directapi.model.common.Value;

/**
 * Created with IntelliJ IDEA.
 * User: mariabye
 * Date: 24.06.13
 * Time: 22:09
 * To change this template use File | Settings | File Templates.
 */
public class CampaignInfoMap<T> extends ModelBeanMap<CampaignInfoMap> {
    //region Fields
    private static final String CAMPAIGN_INFO = "CampaignInfo";

    public static final String LOGIN = "login";
    public static final String CAMPAIGN_ID = "campaignID";
    public static final String NAME = "name";
    public static final String FIO = "FIO";
    public static final String START_DATE = "startDate";
    public static final String SUM = "sum";
    public static final String REST = "rest";
    public static final String STRATEGY = "strategy";
    public static final String CLICK_TRACKING_ENABLED = "clickTrackingEnabled";
    public static final String CURRENCY = "currency";
    public static final String CAMPAIGN_CURRENCY = "campaignCurrency";
    public static final String SOURCE_CAMPAIGN_ID = "sourceCampaignID";
    public static final String CONTEXT_STRATEGY = "contextStrategy";
    public static final String ADDITIONAL_METRIKA_COUNTERS = "additionalMetrikaCounters";
    public static final String SMS_NOTIFICATION = "smsNotification";
    public static final String EMAIL_NOTIFICATION = "emailNotification";
    public static final String STATUS_BEHAVIOR = "statusBehavior";
    public static final String STATUS = "status";
    public static final String TIME_TARGET = "timeTarget";
    public static final String STATUS_CONTEXT_STOP = "statusContextStop";
    public static final String CONTEXT_LIMIT = "contextLimit";
    public static final String CONTEXT_LIMIT_SUM = "contextLimitSum";
    public static final String CONTEXT_PRICE_PERCENT = "contextPricePercent";
    public static final String AUTO_OPTIMIZATION = "autoOptimization";
    public static final String STATUS_METRICA_CONTROL = "statusMetricaControl";
    public static final String DISABLED_DOMAINS = "disabledDomains";
    public static final String DISABLED_IPS = "disabledIps";
    public static final String STATUS_OPEN_STAT = "statusOpenStat";
    public static final String CONSIDER_TIME_TARGET = "considerTimeTarget";
    public static final String AGENCY_NAME = "agencyName";
    public static final String MANAGER_NAME = "managerName";
    public static final String STATUS_SHOW = "statusShow";
    public static final String STATUS_ARCHIVE = "statusArchive";
    public static final String STATUS_ACTIVATING = "statusActivating";
    public static final String STATUS_MODERATE = "statusModerate";
    public static final String IS_ACTIVE = "isActive";
    public static final String MINUS_KEYWORDS = "minusKeywords";
    public static final String ADD_RELEVANT_PHRASES = "addRelevantPhrases";
    public static final String RELEVANT_PHRASES_BUDGET_LIMIT = "relevantPhrasesBudgetLimit";
    public static final String DAY_BUDGET = "dayBudget";
    public static final String DAY_BUDGET_ENABLED = "dayBudgetEnabled";
    public static final String AGENCY_LOGIN = "agencyLogin";
    public static final String CAMPAIGN_TYPE = "campaignType";
    public static final String SHOW_ON_PAGES = "showOnPages";
    public static final String MANAGER_ASSISTANCE = "managerAssistance";
    public static final String SUM_AVAILABLE_FOR_TRANSFER = "sumAvailableForTransfer";
    public static final String MOBILE_BID_ADJUSTMENT = "mobileBidAdjustment";
    public static final String ENABLE_RELATED_KEYWORDS = "enableRelatedKeywords";
    public static final String EXTENDED_AD_TITLE_ENABLED = "extendedAdTitleEnabled";
    public static final String MAINTAIN_NETWORK_CPC = "maintainNetworkCPC";
    public static final String ATTRIBUTION_MODEL = "attribution_model";


    //mobile bid adjustment
    public static final Integer DEFAULT_BID_ADJUSTMENT = 100;
    public static final int MIN_BID_ADJUSTMENT = 50;
    public static final int MAX_BID_ADJUSTMENT = 1300;
    public static final int KEYWORDS_MAX_LENGTH_TOTAL = 20000;

    public CampaignInfoMap(String packageName) {
        super(packageName, CAMPAIGN_INFO);
    }

    public CampaignInfoMap(T campaignInfo) {
        setBean(campaignInfo);
    }

    private String campaignNameInfo() {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        String reflectionPackage = "sun.reflect";
        int i = 0;
        while (i < stackTrace.length && !stackTrace[i].getClassName().startsWith(reflectionPackage)) {
            i++;
        }
        String info = DateTime.now().toString("HH:mm");
        if (i < stackTrace.length) {
            i--;
            while (i >= 0 && stackTrace[i].getMethodName().matches("<.*>")) {
                i--;
            }
            if (i >= 0) {
                String[] classFullName = stackTrace[i].getClassName().split("\\.");
                String className = classFullName[classFullName.length - 1];
                String methodName = stackTrace[i].getMethodName();
                info += " " + className + "." + methodName;
            }
        }
        return info;
    }

    //region Builder
    public CampaignInfoMap defaultCampaign() {
        this.put((FIO), "Иванов Иван Иванович");
        this.put((NAME), "Тестовая кампания API " + campaignNameInfo());
        this.put((CAMPAIGN_ID), 0);
        this.put((START_DATE), DateTime.now().toDate());
        this.put((AUTO_OPTIMIZATION), Value.YES);
        this.put((CONSIDER_TIME_TARGET), Value.YES);
        this.put((STATUS_CONTEXT_STOP), Value.YES);
        this.put((STATUS_BEHAVIOR), Value.YES);
        this.put((DISABLED_DOMAINS), "qwerty.ru");
        this.put((DISABLED_IPS), "11.22.33.44");
        this.put((STATUS_METRICA_CONTROL), Value.NO);
        this.put((STATUS_OPEN_STAT), Value.NO);
        this.put((ADD_RELEVANT_PHRASES), Value.YES);
        this.put((RELEVANT_PHRASES_BUDGET_LIMIT), 100);
        this.put((SMS_NOTIFICATION), new SmsNotificationInfoMap(super.getPackageName()).on().getBean());
        this.put((EMAIL_NOTIFICATION), new EmailNotificationInfoMap(super.getPackageName()).on().getBean());
        this.put((ATTRIBUTION_MODEL), "last_click");

        //Устанавливаем временной таргетинг
        this.put((TIME_TARGET), new TimeTargetMap(super.getPackageName()).noCoefs().getBean());
        //Устанавливаем стратегию на поиске
        this.put((STRATEGY), new StrategyMap(super.getPackageName(), StrategyMap.StrategyType.SEARCH)
                .highestPosition().getBean());
        return this;
    }

    public CampaignInfoMap withStartDate(Date startDate) {
        this.put(START_DATE, startDate);
        return this;
    }

    public CampaignInfoMap withAttributionModel(String attribution_model) {
        this.put(ATTRIBUTION_MODEL, attribution_model);
        return this;
    }

    public CampaignInfoMap withStatusBehavior(String statusBehavior) {
        this.put(STATUS_BEHAVIOR, statusBehavior);
        return this;
    }

    public CampaignInfoMap withAddRelevantPhrases(String addRelevantPhrases) {
        this.put(ADD_RELEVANT_PHRASES, addRelevantPhrases);
        return this;
    }

    public CampaignInfoMap withRelevantPhrasesBudgetLimit(Integer relevantPhrasesBudgetLimit) {
        this.put(RELEVANT_PHRASES_BUDGET_LIMIT, relevantPhrasesBudgetLimit);
        return this;
    }

    public CampaignInfoMap withStrategy(StrategyMap strategy) {
        if (strategy != null) {
            this.put(STRATEGY, strategy.getBean());
        } else {
            this.put(STRATEGY, null);
        }
        return this;
    }

    public CampaignInfoMap withContextStrategy(StrategyMap contextStrategy) {
        if (contextStrategy != null) {
            this.put((CONTEXT_STRATEGY), contextStrategy.getBean());
        } else {
            this.put(CONTEXT_STRATEGY, null);
        }
        return this;
    }

    public CampaignInfoMap withTimeTarget(TimeTargetMap timeTarget) {
        this.put((TIME_TARGET), timeTarget.getBean());
        return this;
    }

    public CampaignInfoMap withLogin(String login) {
        this.put((LOGIN), login);
        return this;
    }

    public CampaignInfoMap withAgencyLogin(String agencyLogin) {
        this.put((AGENCY_LOGIN), agencyLogin);
        return this;
    }

    public CampaignInfoMap withCurrency(Currency currency) {
        if (currency != null && currency != Currency.YND_FIXED) {
            this.put((CURRENCY), currency.value());
        } else {
            this.put((CURRENCY), null);
        }
        return this;
    }

    public CampaignInfoMap withCampaignCurrency(Currency currency) {
        if (currency != null && currency != Currency.YND_FIXED) {
            this.put((CAMPAIGN_CURRENCY), currency.value());
        } else {
            this.put((CAMPAIGN_CURRENCY), null);
        }
        return this;
    }

    public CampaignInfoMap withCampaignType(String campaignType) {
        put((CAMPAIGN_TYPE), campaignType);
        return this;
    }

    public CampaignInfoMap withManagerAssistance(String managerAssistance) {
        put((MANAGER_ASSISTANCE), managerAssistance);
        return this;
    }

    public CampaignInfoMap withCampaignID(int campaignID) {
        put((CAMPAIGN_ID), campaignID);
        return this;
    }

    public CampaignInfoMap withManagerName(String managerName) {
        put((MANAGER_NAME), managerName);
        return this;
    }

    public CampaignInfoMap withFIO(String fio) {
        put((FIO), fio);
        return this;
    }

    public CampaignInfoMap withDisabledDomains(String disabledDomains) {
        put((DISABLED_DOMAINS), disabledDomains);
        return this;
    }

    public CampaignInfoMap withMinusKeywords(String... minusKeywords) {
        put((MINUS_KEYWORDS), minusKeywords);
        return this;
    }

    public CampaignInfoMap withAdditionaMetricaCounters(int[] ids) {
        this.put((ADDITIONAL_METRIKA_COUNTERS), ids);
        return this;
    }

    public CampaignInfoMap withStatusMetricaControl(String status) {
        this.put((STATUS_METRICA_CONTROL), status);
        return this;
    }

    public CampaignInfoMap withAutoOptimization(String autoOptimization) {
        this.put(AUTO_OPTIMIZATION, autoOptimization);
        return this;
    }

    public CampaignInfoMap withName(String name) {
        this.put((NAME), name);
        return this;
    }

    public CampaignInfoMap withDayBudget(DayBudgetInfoMap dayBudgetInfoMap) {
        if (dayBudgetInfoMap != null) {
            put(DAY_BUDGET, dayBudgetInfoMap.getBean());
        } else {
            put(DAY_BUDGET, null);
        }
        return this;
    }

    public CampaignInfoMap withDayBudgetEnabled(String value) {
        put(DAY_BUDGET_ENABLED, value);
        return this;
    }

    public CampaignInfoMap withEmailNotification(EmailNotificationInfoMap emailNotificationInfoMap) {
        if (emailNotificationInfoMap != null) {
            put(EMAIL_NOTIFICATION, emailNotificationInfoMap.getBean());
        } else {
            put(EMAIL_NOTIFICATION, null);
        }
        return this;
    }

    public CampaignInfoMap withSmsNotification(SmsNotificationInfoMap smsNotificationInfoMap) {
        if (smsNotificationInfoMap != null) {
            put(SMS_NOTIFICATION, smsNotificationInfoMap.getBean());
        } else {
            put(SMS_NOTIFICATION, null);
        }
        return this;
    }

    public CampaignInfoMap withContextLimit(String contextLimit) {
        put(CONTEXT_LIMIT, contextLimit);
        return this;
    }

    public CampaignInfoMap withContextLimitSum(Integer contextLimitSum) {
        put(CONTEXT_LIMIT_SUM, contextLimitSum);
        return this;
    }

    public CampaignInfoMap withContextPricePercent(Integer contextPricePercent) {
        put(CONTEXT_PRICE_PERCENT, contextPricePercent);
        return this;
    }

    public CampaignInfoMap withSum(Float sum) {
        put(SUM, sum);
        return this;
    }

    public CampaignInfoMap withRest(Float rest) {
        put(REST, rest);
        return this;
    }

    public CampaignInfoMap withSumAvailableForTransfer(Float sumAvailableForTransfer) {
        put(SUM_AVAILABLE_FOR_TRANSFER, sumAvailableForTransfer);
        return this;
    }

    public CampaignInfoMap withMobileBidAdjustment(Integer mobileAdjustment) {
        put(MOBILE_BID_ADJUSTMENT, mobileAdjustment);
        return this;
    }

    public CampaignInfoMap withShowOnPages(String[] showOnPages) {
        put(SHOW_ON_PAGES, showOnPages);
        return this;
    }

    public CampaignInfoMap withIsActive(String isActive) {
        put(IS_ACTIVE, isActive);
        return this;
    }

    public CampaignInfoMap withEnableRelatedKeywords(String value) {
        put(ENABLE_RELATED_KEYWORDS, value);
        return this;
    }

    public CampaignInfoMap withExtendedAdTitleEnabled(String value) {
        put(EXTENDED_AD_TITLE_ENABLED, value);
        return this;
    }

    public CampaignInfoMap withDisableIps(String value) {
        put(DISABLED_IPS, value);
        return this;
    }

    public CampaignInfoMap withMaintainNetworkCPC(String value) {
        put(MAINTAIN_NETWORK_CPC, value);
        return this;
    }

    public CampaignInfoMap withConsiderTimeTarget(String considerTimeTarget) {
        put((CONSIDER_TIME_TARGET), considerTimeTarget);
        return this;
    }

    public CampaignInfoMap withStatusOpenStat(String statusOpenStat) {
        put((STATUS_OPEN_STAT), statusOpenStat);
        return this;
    }

    public CampaignInfoMap withClickTrackingEnabled(String clickTrackingEnabled) {
        put((CLICK_TRACKING_ENABLED), clickTrackingEnabled);
        return this;
    }
}
