package ru.yandex.webmaster3.admin.action.spamban;

import com.datastax.driver.core.utils.UUIDs;
import org.joda.time.Instant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.admin.security.action.AbstractAdminRequest;
import ru.yandex.webmaster3.admin.security.action.AdminAction;
import ru.yandex.webmaster3.admin.security.action.AdminUserIdAware;
import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.http.ActionResponse;
import ru.yandex.webmaster3.core.http.RequestQueryProperty;
import ru.yandex.webmaster3.core.http.WebmasterErrorResponse;
import ru.yandex.webmaster3.core.http.WriteAction;
import ru.yandex.webmaster3.storage.admin.security.AccessObjectEnum;
import ru.yandex.webmaster3.storage.user.SpamBanRule;
import ru.yandex.webmaster3.storage.user.dao.SpamBanRulesYDao;
import ru.yandex.webmaster3.storage.util.ydb.exception.WebmasterYdbException;

/**
 * Created by ifilippov5 on 23.12.16.
 */
@WriteAction
@Description("Добавление правила. Добавленное правило активно.")
@Component("/admin/spamban/rule/add")
public class AddRuleAction extends AdminAction<AddRuleAction.Request, AddRuleAction.Response> {
    @Autowired
    private SpamBanRulesYDao spamBanRulesYDao;

    public AddRuleAction() {
        super(AccessObjectEnum.SPAM_BAN);
    }

    @Override
    public AddRuleAction.Response process(AddRuleAction.Request request) throws WebmasterException {
        try {
            if (!spamBanRulesYDao.insertRule(new SpamBanRule(UUIDs.timeBased(), request.getMask(), request.getSubnetLength(), request.getAdminUserId(),
                    true, request.getCause(), Instant.now())))
                return new MaskAlreadyAddedError();
        } catch (WebmasterYdbException e) {
            throw new WebmasterException("Unable to add rule",
                    new WebmasterErrorResponse.YDBErrorResponse(this.getClass(), e), e);
        } catch (IllegalArgumentException e) {
            throw new WebmasterException(e.getMessage(), new WebmasterErrorResponse.IllegalParameterValueResponse(getClass(), "mask", request.getMask()));
        }
        return new NormalResponse();
    }

    public enum Errors {
        MASK_ALREADY_ADDED,
    }

    public static class Request extends AbstractAdminRequest implements AdminUserIdAware {
        private String mask;
        private int subnetLength;
        private long adminUserId;
        private String cause;

        public String getMask() {
            return mask;
        }

        @RequestQueryProperty(required = true)
        public void setMask(String mask) {
            this.mask = mask;
        }

        public int getSubnetLength() {
            return subnetLength;
        }

        @RequestQueryProperty(required = true)
        public void setSubnetLength(int subnetLength) {
            this.subnetLength = subnetLength;
        }

        @Override
        public long getAdminUserId() {
            return adminUserId;
        }

        @Override
        public void setAdminUserId(long userId) {
            adminUserId = userId;
        }

        public String getCause() {
            return cause;
        }

        @RequestQueryProperty()
        public void setCause(String cause) {
            this.cause = cause;
        }
    }

    public abstract static class Response implements ActionResponse {
    }

    public static class NormalResponse extends Response implements ActionResponse.NormalResponse {
    }

    @Description("Пара (mask,subnetLength) уже добавлена")
    public static class MaskAlreadyAddedError extends Response implements ActionResponse.ErrorResponse {

        @Override
        public Enum<?> getCode() {
            return Errors.MASK_ALREADY_ADDED;
        }
    }
}
