package com.cronutils.descriptor.refactor;

import java.text.ChoiceFormat;
import java.text.Format;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import com.cronutils.model.Cron;
import com.cronutils.model.field.CronField;
import com.cronutils.model.field.CronFieldName;
import com.cronutils.model.field.expression.Always;
import com.cronutils.model.field.expression.Every;
import com.cronutils.model.field.expression.On;
import com.cronutils.utils.Preconditions;
import com.cronutils.utils.StringUtils;

public class TimeDescriptor {

    private final ResourceBundle resourceBundle;

    public TimeDescriptor(final ResourceBundle resourceBundle) {
        this.resourceBundle = Preconditions.checkNotNull(resourceBundle, "The resource bundle must not be null");
    }


    public String describe(final Cron cron) {
        return describe(cron.retrieveFieldsAsMap());
    }

    private String describe(final Map<CronFieldName, CronField> expressions) {

        if (expressions.containsKey(CronFieldName.SECOND)) {
            final CronField cronField = expressions.get(CronFieldName.SECOND);
            if (cronField.getExpression() instanceof Always) {
                return describeEverySecond(1);
            } else if (cronField.getExpression() instanceof On) {
                return describeAtSecond(((On)cronField.getExpression()).getTime().getValue());
            } else if (cronField.getExpression() instanceof Every) {
                return describeEverySecond(((Every)cronField.getExpression()).getPeriod().getValue());
            }
        }


        return StringUtils.EMPTY;
    }

    private String describeEverySecond(final int second) {
        final double[] secondsLimit = {1, 2};
        final String[] secondsStrings = {
                resourceBundle.getString("oneSecond"),
                resourceBundle.getString("multipleSeconds")
        };
        final double[] everyLimit = {1,2};
        final String[] everyStrings = {
                resourceBundle.getString("every_one"),
                resourceBundle.getString("every_multi")
        };

        final ChoiceFormat secondsChoiceFormat = new ChoiceFormat(secondsLimit, secondsStrings);
        final ChoiceFormat everyChoiceFormat = new ChoiceFormat(everyLimit, everyStrings);
        final String pattern = resourceBundle.getString("pattern_every_seconds");

        final MessageFormat messageFormat = new MessageFormat(pattern, Locale.UK);

        final Format[] formats = { everyChoiceFormat, secondsChoiceFormat, NumberFormat.getInstance() };
        messageFormat.setFormats(formats);
        final Object[] messageArguments = {second, second, second };
        final String result = messageFormat.format(messageArguments);
        return result;
    }

    private String describeAtSecond(final int second) {

        final String pattern = resourceBundle.getString("pattern_at_second");

        final MessageFormat messageFormat = new MessageFormat(pattern, Locale.UK);
        final Format[] formats = {NumberFormat.getInstance()};
        messageFormat.setFormats(formats);

        final Object[] messageArguments = { second };
        final String result = messageFormat.format(messageArguments);
        return result;
    }

}