package ru.yandex.autodoc.wmtools.params.fetch;

import ru.yandex.autodoc.common.doc.abstracts.ParamsDocRegistrar;
import ru.yandex.autodoc.common.util.enums.IEnumResolver;
import ru.yandex.autodoc.wmtools.params.fetch.impl.*;
import ru.yandex.autodoc.wmtools.params.fetch.json.JsonValueView;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author avhaliullin
 */
public class ParamViews {
    protected ParamViews() {
    }

    public static StringViewBuilder stringBuilder(String paramName) {
        return new StringViewBuilder(paramName);
    }

    public static ParamView<String> stringView(ParamsDocRegistrar registrar, String param, boolean trim, String desc) {
        return stringBuilder(param).trim(trim).build(registrar, desc);
    }

    public static ParamView<String> requiredStringView(ParamsDocRegistrar registrar, String param, boolean trim, String desc) {
        return stringBuilder(param).required().trim(trim).build(registrar, desc);
    }

    // Integer

    public static ParamView<Integer> intView(ParamsDocRegistrar registrar, String name, boolean required, Integer minValue,
                                             Integer maxValue, Integer defaultValue, String desc) {
        return new IntegerViewSingle(registrar, name, required, minValue, maxValue, defaultValue, desc);
    }

    public static ParamView<Integer> intView(ParamsDocRegistrar registrar, String name, int defaultValue, String desc) {
        return intView(registrar, name, false, null, null, defaultValue, desc);
    }

    public static ParamView<Integer> intView(ParamsDocRegistrar registrar, String name, String desc) {
        return intView(registrar, name, false, null, null, null, desc);
    }

    public static ParamView<Integer> requiredIntView(ParamsDocRegistrar registrar, String name, String desc) {
        return intView(registrar, name, true, null, null, null, desc);
    }

    public static ParamView<Integer> requiredIntView(ParamsDocRegistrar registrar, String name, Integer minValue, Integer maxValue, String desc) {
        return intView(registrar, name, true, minValue, maxValue, null, desc);
    }

    // Long

    public static ParamView<Long> longView(ParamsDocRegistrar registrar, String name, boolean required, Long defaultValue, String desc) {
        return new LongViewSingle(registrar, name, required, defaultValue, desc);
    }

    public static ParamView<Long> longView(ParamsDocRegistrar registrar, String name, String desc) {
        return longView(registrar, name, false, null, desc);
    }

    public static ParamView<Long> requiredLongView(ParamsDocRegistrar registrar, String name, String desc) {
        return longView(registrar, name, true, null, desc);
    }

    // Boolean

    public static ParamView<Boolean> booleanView(ParamsDocRegistrar registrar, String name, boolean required, Boolean defaultValue, String desc) {
        return new BooleanViewSingle(registrar, name, required, defaultValue, desc);
    }

    public static ParamView<Boolean> requiredBooleanView(ParamsDocRegistrar registrar, String name, String desc) {
        return booleanView(registrar, name, true, null, desc);
    }

    public static ParamView<Boolean> requiredBooleanView(ParamsDocRegistrar registrar, String name, boolean defaultValue, String desc) {
        return booleanView(registrar, name, true, defaultValue, desc);
    }

    public static ParamView<Boolean> booleanView(ParamsDocRegistrar registrar, String name, boolean defaultValue, String desc) {
        return booleanView(registrar, name, false, defaultValue, desc);
    }

    // Enum

    public static <T extends Enum<T>> ParamView<T> enumView(ParamsDocRegistrar registrar, String name, IEnumResolver<T> resolver, boolean required, T defaultValue, String desc) {
        return new EnumViewSingle<>(registrar, name, resolver, required, defaultValue, desc);
    }

    public static <T extends Enum<T>> ParamView<T> enumView(ParamsDocRegistrar registrar, String name, IEnumResolver<T> resolver, T dflt, String desc) {
        return enumView(registrar, name, resolver, false, dflt, desc);
    }

    public static <T extends Enum<T>> ParamView<T> enumView(ParamsDocRegistrar registrar, String name, IEnumResolver<T> resolver, String desc) {
        return enumView(registrar, name, resolver, null, desc);
    }

    public static <T extends Enum<T>> ParamView<T> requiredEnumView(ParamsDocRegistrar registrar, String name, IEnumResolver<T> resolver, String desc) {
        return enumView(registrar, name, resolver, true, null, desc);
    }

    public static <T> ParamView<T> jsonView(ParamsDocRegistrar registrar, String name, boolean required,
                                            JsonValueView<T, ?> jsonView, T defaultValue, String desc) {
        return new JsonViewSingle<>(registrar, name, required, jsonView, defaultValue, desc);
    }

    public static <T> ParamView<T> requiredJsonView(ParamsDocRegistrar registrar, String name, JsonValueView<T, ?> jsonView, String desc) {
        return jsonView(registrar, name, true, jsonView, null, desc);
    }

    public static <T> JsonArrayViewBuilder<T> jsonArrayBuilder(String name, JsonValueView<T, ?> elementView) {
        return new JsonArrayViewBuilder<>(name, elementView);
    }

    // Old date

    private static final DateFormat DEFAULT_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

    public static ParamView<Date> oldDateView(ParamsDocRegistrar registrar, String name, DateFormat dateFormat,
                                              boolean required, Date defaultValue, String desc) {
        return new OldDateViewSingle(registrar, name, dateFormat, required, defaultValue, desc);
    }

    public static ParamView<Date> oldDateView(ParamsDocRegistrar registrar, String name, String desc) {
        return oldDateView(registrar, name, DEFAULT_DATE_FORMAT, false, null, desc);
    }

    public static ParamView<Date> requiredOldDateView(ParamsDocRegistrar registrar, String name, String desc) {
        return oldDateView(registrar, name, DEFAULT_DATE_FORMAT, true, null, desc);
    }

    // Color

    public static ParamView<String> colorView(ParamsDocRegistrar registrar, String name, boolean required, boolean allowTransparent,
                                              String defaultValue, String desc) {
        return new ColorViewSingle(registrar, name, required, allowTransparent, defaultValue, desc);
    }

    public static ParamView<String> requiredColorView(ParamsDocRegistrar registrar, String name, boolean allowTransparent,
                                                      String desc) {
        return colorView(registrar, name, true, allowTransparent, null, desc);
    }

    // Font size

    public static ParamView<Integer> fontSizeView(ParamsDocRegistrar registrar, String name, String desc) {
        return intView(registrar, name, false, 1, 128, null, desc);
    }

    public static ParamView<Integer> requiredFontSizeView(ParamsDocRegistrar registrar, String name, String desc) {
        return intView(registrar, name, true, 1, 128, 14, desc);
    }

    // Multiparam string

    public static MultiStringBuilder multiStringBuilder(String name) {
        return new MultiStringBuilder(name);
    }

    public static SeparatedStringViewBuilder separatedStringBuilder(String name) {
        return new SeparatedStringViewBuilder(name);
    }

    // Multiparam long

    public static MultiParamView<Long> multiLongView(ParamsDocRegistrar registrar, String name, String desc) {
        return multiLongBuilder(name).build(registrar, desc);
    }

    public static MultiLongBuilder multiLongBuilder(String name) {
        return new MultiLongBuilder(name);
    }

    // Multiparam int

    public static MultiParamView<Integer> multiIntView(ParamsDocRegistrar registrar, String name, String desc) {
        return multiIntBuilder(name).build(registrar, desc);
    }

    public static MultiIntBuilder multiIntBuilder(String name) {
        return new MultiIntBuilder(name);
    }
}
