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

import com.yandex.direct.api.v5.campaigns.CampaignAddItem;
import com.yandex.direct.api.v5.campaigns.CpmBannerCampaignAddItem;
import com.yandex.direct.api.v5.campaigns.DailyBudget;
import com.yandex.direct.api.v5.campaigns.DynamicTextCampaignAddItem;
import com.yandex.direct.api.v5.campaigns.MobileAppCampaignAddItem;
import com.yandex.direct.api.v5.campaigns.SmartCampaignAddItem;
import com.yandex.direct.api.v5.campaigns.TextCampaignAddItem;
import com.yandex.direct.api.v5.campaigns.TimeTargetingAdd;
import com.yandex.direct.api.v5.general.ArrayOfString;
import org.joda.time.DateTime;

import ru.yandex.autotests.directapi.enums.CampaignType;
import ru.yandex.autotests.directapi.model.api5.general.ArrayOfStringMap;

import static ru.yandex.qa.balance.tools.common.utils.ConvertUtils.asLong;

/**
 * Created by pavryabov on 05.08.15.
 */
public class CampaignAddItemMap extends CampaignBaseMap<CampaignAddItemMap> {

    public static final String NAME = "name";
    public static final String START_DATE = "startDate";
    public static final String DAILY_BUDGET = "dailyBudget";
    public static final String END_DATE = "endDate";
    public static final String NEGATIVE_KEYWORDS = "negativeKeywords";
    public static final String BLOCKED_IPS = "blockedIps";
    public static final String EXCLUDED_SITES = "excludedSites";
    public static final String TEXT_CAMPAIGN = "textCampaign";
    public static final String MOBILE_APP_CAMPAIGN = "mobileAppCampaign";
    public static final String DYNAMIC_TEXT_CAMPAIGN = "dynamicTextCampaign";
    public static final String CPM_BANNER_CAMPAIGN = "cpmBannerCampaign";
    public static final String SMART_CAMPAIGN = "smartCampaign";

    public static final String DEFAULT_NAME = "Тестовая кампания API5";
    public static final String DEFAULT_CLIENT_INFO = "Иванов Иван Иванович";

    public static final int MAX_NEGATIVE_KEYWORDS_LENGTH = 20000;
    public static final int MAX_WORDS_IN_NEGATIVE_KEYPHRASE = 7;
    public static final int MAX_NAME_LENGTH = 255;
    public static final int MAX_EMAIL_LENGTH = 255;
    public static final int MAX_CLIENT_INFO_LENGTH = 255;
    public static final int MAX_AMOUNT_OF_BLOCKED_IPS = 25;
    public static final int MAX_AMOUNT_OF_EXCLUDED_SITES = 1000;

    public static final String DATE_PATTERN = "yyyy-MM-dd";

    public CampaignAddItemMap() {
        super();
        setBean(new CampaignAddItem());
    }

    public CampaignAddItemMap(CampaignAddItem campaignAddItem) {
        super();
        setBean(campaignAddItem);
    }

    public CampaignAddItemMap put(String fieldName, Object value) {
        super.put(fieldName, value);
        return this;
    }

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

    public CampaignAddItemMap withStartDate(String startDate) {
        this.put(START_DATE, startDate);
        return this;
    }

    public CampaignAddItemMap withDailyBudget(DailyBudgetMap dailyBudgetMap) {
        DailyBudget dailyBudget =
                ((dailyBudgetMap == null) ? null : (DailyBudget) (dailyBudgetMap.getBean()));
        this.put(DAILY_BUDGET, dailyBudget);
        return this;
    }

    public CampaignAddItemMap withEndDate(String endDate) {
        this.put(END_DATE, endDate);
        return this;
    }

    public CampaignAddItemMap withNegativeKeywords(ArrayOfStringMap arrayOfStringMap) {
        ArrayOfString arrayOfString =
                (ArrayOfString) ((arrayOfStringMap == null) ? null : arrayOfStringMap.getBean());
        this.put(NEGATIVE_KEYWORDS, arrayOfString);
        return this;
    }

    public CampaignAddItemMap withNegativeKeywords(String... items) {
        ArrayOfStringMap arrayOfStringMap = (items == null) ? null : new ArrayOfStringMap().withItems(items);
        return this.withNegativeKeywords(arrayOfStringMap);
    }

    public CampaignAddItemMap withBlockedIps(ArrayOfStringMap arrayOfStringMap) {
        ArrayOfString arrayOfString =
                (ArrayOfString) ((arrayOfStringMap == null) ? null : arrayOfStringMap.getBean());
        this.put(BLOCKED_IPS, arrayOfString);
        return this;
    }

    public CampaignAddItemMap withBlockedIps(String... items) {
        ArrayOfStringMap arrayOfStringMap = (items == null) ? null : new ArrayOfStringMap().withItems(items);
        return this.withBlockedIps(arrayOfStringMap);
    }

    public CampaignAddItemMap withExcludedSites(ArrayOfStringMap arrayOfStringMap) {
        ArrayOfString arrayOfString =
                (ArrayOfString) ((arrayOfStringMap == null) ? null : arrayOfStringMap.getBean());
        this.put(EXCLUDED_SITES, arrayOfString);
        return this;
    }

    public CampaignAddItemMap withExcludedSites(String... items) {
        ArrayOfStringMap arrayOfStringMap = (items == null) ? null : new ArrayOfStringMap().withItems(items);
        return this.withExcludedSites(arrayOfStringMap);
    }

    public CampaignAddItemMap withTextCampaign(TextCampaignAddItemMap textCampaignAddItemMap) {
        TextCampaignAddItem textCampaignAddItem =
                ((textCampaignAddItemMap == null) ? null : (TextCampaignAddItem) (textCampaignAddItemMap.getBean()));
        this.put(TEXT_CAMPAIGN, textCampaignAddItem);
        return this;
    }

    public CampaignAddItemMap withMobileAppCampaign(MobileAppCampaignAddItemMap mobileAppCampaignAddItemMap) {
        MobileAppCampaignAddItem mobileAppCampaignAddItem =
                ((mobileAppCampaignAddItemMap == null) ? null
                        : (MobileAppCampaignAddItem) (mobileAppCampaignAddItemMap.getBean()));
        this.put(MOBILE_APP_CAMPAIGN, mobileAppCampaignAddItem);
        return this;
    }

    public CampaignAddItemMap withDynamicTextCampaign(DynamicTextCampaignAddItemMap dynamicTextCampaignAddItemMap) {
        DynamicTextCampaignAddItem dynamicTextCampaignAddItem =
                ((dynamicTextCampaignAddItemMap == null) ? null
                        : (DynamicTextCampaignAddItem) (dynamicTextCampaignAddItemMap.getBean()));
        this.put(DYNAMIC_TEXT_CAMPAIGN, dynamicTextCampaignAddItem);
        return this;
    }

    public CampaignAddItemMap withSmartCampaign(SmartCampaignAddItemMap smartCampaignAddItemMap) {
        SmartCampaignAddItem smartCampaignAddItemAddItem =
                ((smartCampaignAddItemMap == null) ? null
                        : (SmartCampaignAddItem) smartCampaignAddItemMap.getBean());
        this.put(SMART_CAMPAIGN, smartCampaignAddItemAddItem);
        return this;
    }

    public CampaignAddItemMap withCpmBannerCampaign(CpmBannerCampaignAddItemMap cpmBannerCampaignAddItemMap) {
        CpmBannerCampaignAddItem cpmBannerCampaignAddItem =
                ((cpmBannerCampaignAddItemMap == null) ? null
                        : (CpmBannerCampaignAddItem) (cpmBannerCampaignAddItemMap.getBean()));
        this.put(CPM_BANNER_CAMPAIGN, cpmBannerCampaignAddItem);
        return this;
    }

    public CampaignAddItemMap defaultCampaignAddItem() {
        return this
                .withName(DEFAULT_NAME + campaignNameInfo())
                .withStartDate(DateTime.now().toString(DATE_PATTERN));
    }

    public CampaignAddItemMap withTimeTargeting(TimeTargetingAddMap timeTargetingAddMap) {
        TimeTargetingAdd timeTargeting =
                (TimeTargetingAdd) ((timeTargetingAddMap == null) ? null : timeTargetingAddMap.getBean());
        this.put(TIME_TARGETING, timeTargeting);
        return this;
    }

    public CampaignAddItemMap withDefaultTextCampaign() {
        return this.withTextCampaign(new TextCampaignAddItemMap().defaultTextCampaign());
    }

    public CampaignAddItemMap withDefaultDynamicTextCampaign() {
        return this.withDynamicTextCampaign(new DynamicTextCampaignAddItemMap().defaultDynamicTextCampaign());
    }

    public CampaignAddItemMap withDefaultMobileAppCampaign() {
        return this.withMobileAppCampaign(new MobileAppCampaignAddItemMap().defaultMobileAppCampaign());
    }

    public CampaignAddItemMap withDefaultCpmBannerCampaign() {
        return this.withCpmBannerCampaign(new CpmBannerCampaignAddItemMap().defaultCpmBannerCampaign());
    }

    public CampaignAddItemMap withDefaultSmartCampaign(Integer counter) {
        return this.withSmartCampaign(
                new SmartCampaignAddItemMap().defaultSmartCampaign().withCounterId(asLong(counter)));
    }

    public CampaignAddItemMap withDefaultCampaign(CampaignType type) {
        switch (type) {
            case TEXT:
                this.put(TEXT_CAMPAIGN, new TextCampaignAddItemMap().defaultTextCampaign().getBean());
                break;
            case MOBILE_CONTENT:
                this.put(MOBILE_APP_CAMPAIGN, new MobileAppCampaignAddItemMap().defaultMobileAppCampaign().getBean());
                break;
            case DYNAMIC:
                this.put(DYNAMIC_TEXT_CAMPAIGN,
                        new DynamicTextCampaignAddItemMap().defaultDynamicTextCampaign().getBean());
                break;
            case CPM_BANNER:
                this.put(CPM_BANNER_CAMPAIGN,
                        new CpmBannerCampaignAddItemMap().defaultCpmBannerCampaign().getBean());
                break;
        }
        return this;
    }

    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;
    }
}
