package org.ovirt.engine.ui.uicommonweb.models.gluster;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.ovirt.engine.core.common.TimeZoneType;
import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotScheduleRecurrence;
import org.ovirt.engine.core.compat.DayOfWeek;
import org.ovirt.engine.ui.uicommonweb.Linq;
import org.ovirt.engine.ui.uicommonweb.models.EntityModel;
import org.ovirt.engine.ui.uicommonweb.models.ListModel;
import org.ovirt.engine.ui.uicommonweb.models.Model;
import org.ovirt.engine.ui.uicommonweb.validation.AsciiNameValidation;
import org.ovirt.engine.ui.uicommonweb.validation.IValidation;
import org.ovirt.engine.ui.uicommonweb.validation.LengthValidation;
import org.ovirt.engine.ui.uicommonweb.validation.NotEmptyValidation;
import org.ovirt.engine.ui.uicompat.ConstantsManager;
import org.ovirt.engine.ui.uicompat.EventArgs;
import org.ovirt.engine.ui.uicompat.IEventListener;
import org.ovirt.engine.ui.uicompat.PropertyChangedEventArgs;
public class GlusterVolumeSnapshotModel extends Model {
private EntityModel<String> dataCenter;
private EntityModel<String> clusterName;
private EntityModel<String> volumeName;
private EntityModel<String> snapshotName;
private EntityModel<String> description;
private ListModel<GlusterVolumeSnapshotScheduleRecurrence> recurrence;
private ListModel<String> interval;
private ListModel<EndDateOptions> endByOptions;
private EntityModel<Date> endDate;
private boolean generalTabVisible;
private boolean scheduleTabVisible;
private ListModel<Map.Entry<String, String>> timeZones;
private EntityModel<Date> startAt;
private EntityModel<Date> executionTime;
private ListModel<List<DayOfWeek>> daysOfWeek;
private ListModel<String> daysOfMonth;
//Listeners should be registered only once and not initially itself but only after a first validation occurs after user clicks on ok.
private boolean listenersRegistered = false;
private EntityModel<Boolean> disableCliSchedule;
public GlusterVolumeSnapshotModel(boolean generalTabVisible, boolean scheduleTabVisible) {
init();
setGeneralTabVisible(generalTabVisible);
setScheduleTabVisible(scheduleTabVisible);
disableCliSchedule.setEntity(false);
disableCliSchedule.setIsAvailable(false);
}
private void init() {
setDataCenter(new EntityModel<String>());
setClusterName(new EntityModel<String>());
setVolumeName(new EntityModel<String>());
setSnapshotName(new EntityModel<String>());
setDescription(new EntityModel<String>());
setRecurrence(new ListModel<GlusterVolumeSnapshotScheduleRecurrence>());
setInterval(new ListModel<String>());
setEndByOptions(new ListModel<EndDateOptions>());
setTimeZones(new ListModel<Map.Entry<String, String>>());
setDaysOfMonth(new ListModel<String>());
setStartAt(new EntityModel<>(new Date()));
setEndDate(new EntityModel<>(new Date()));
setExecutionTime(new EntityModel<>(new Date()));
setDisableCliSchedule(new EntityModel<>(false));
initIntervals();
initTimeZones();
recurrence.setItems(Arrays.asList(GlusterVolumeSnapshotScheduleRecurrence.values()),
GlusterVolumeSnapshotScheduleRecurrence.UNKNOWN);
endByOptions.setItems(Arrays.asList(EndDateOptions.values()));
List<String> values = new ArrayList<>();
for (DayOfWeek day : DayOfWeek.values()) {
values.add(day.toString().substring(0, 3));
}
daysOfWeek = new ListModel<>();
List<DayOfWeek> daysList = Arrays.asList(DayOfWeek.values());
List<List<DayOfWeek>> list = new ArrayList<>();
list.add(daysList);
daysOfWeek.setItems(list, new ArrayList<DayOfWeek>());
}
private void initValueChangeListeners() {
IEventListener<EventArgs> onPropertyChangeValidate = (ev, sender, args) -> validate(true);
getSnapshotName().getEntityChangedEvent().addListener(onPropertyChangeValidate);
getDaysOfTheWeek().getSelectedItemChangedEvent().addListener(onPropertyChangeValidate);
getDaysOfMonth().getSelectedItemChangedEvent().addListener(onPropertyChangeValidate);
getEndDate().getEntityChangedEvent().addListener(onPropertyChangeValidate);
}
private void validateSnapshotName() {
getSnapshotName().validateEntity(new IValidation[] { new NotEmptyValidation(), new LengthValidation(128),
new AsciiNameValidation() });
}
private void validateEndDate() {
if (getRecurrence().getSelectedItem() != GlusterVolumeSnapshotScheduleRecurrence.UNKNOWN
&& getEndByOptions().getSelectedItem() == EndDateOptions.HasEndDate
&& getEndDate().getEntity().compareTo(getStartAt().getEntity()) <= 0) {
String message = ConstantsManager.getInstance().getConstants().endDateBeforeStartDate();
getEndDate().setInvalidityReasons(Collections.singletonList(message));
getEndDate().setIsValid(false);
} else {
getEndDate().setInvalidityReasons(new ArrayList<String>());
getEndDate().setIsValid(true);
}
}
private void validateDaysOfMonth() {
if (getRecurrence().getSelectedItem() == GlusterVolumeSnapshotScheduleRecurrence.MONTHLY) {
if (getDaysOfMonth().getSelectedItem() == null || getDaysOfMonth().getSelectedItem().equals("")) {//$NON-NLS-1$
String message = ConstantsManager.getInstance().getConstants().noMonthDaysSelectedMessage();
getDaysOfMonth().setInvalidityReasons(Collections.singletonList(message));
getDaysOfMonth().setIsValid(false);
} else if (getDaysOfMonth().getSelectedItem().contains(",L") || getDaysOfMonth().getSelectedItem().contains("L,")) {//$NON-NLS-1$//$NON-NLS-2$
String message = ConstantsManager.getInstance().getConstants().lastDayMonthCanBeSelectedAlone();
getDaysOfMonth().setInvalidityReasons(Collections.singletonList(message));
getDaysOfMonth().setIsValid(false);
} else {
getDaysOfMonth().setInvalidityReasons(new ArrayList<String>());
getDaysOfMonth().setIsValid(true);
}
}
}
private void validateDaysOfWeek() {
if (getRecurrence().getSelectedItem() == GlusterVolumeSnapshotScheduleRecurrence.WEEKLY) {
if (getDaysOfTheWeek().getSelectedItem() == null || getDaysOfTheWeek().getSelectedItem().isEmpty()) {
String message = ConstantsManager.getInstance().getConstants().noWeekDaysSelectedMessage();
getDaysOfTheWeek().setInvalidityReasons(Collections.singletonList(message));
getDaysOfTheWeek().setIsValid(false);
} else {
getDaysOfTheWeek().setInvalidityReasons(new ArrayList<String>());
getDaysOfTheWeek().setIsValid(true);
}
}
}
private void initIntervals() {
List<String> intervals = new ArrayList<>();
int mins = 0;
for (int nThMin = 1; mins < 55; nThMin++) {
mins = nThMin * 5;
intervals.add(String.valueOf(mins));
}
getInterval().setItems(intervals);
}
private void initTimeZones() {
Map<String, String> timeZones = TimeZoneType.GENERAL_TIMEZONE.getTimeZoneList();
getTimeZones().setItems(timeZones.entrySet());
getTimeZones().setSelectedItem(Linq.firstOrNull(timeZones.entrySet(),
item -> item.getValue().startsWith("(GMT) Greenwich"))); //$NON-NLS-1$
}
public EntityModel<String> getDataCenter() {
return this.dataCenter;
}
public void setDataCenter(EntityModel<String> dataCenter) {
this.dataCenter = dataCenter;
}
public EntityModel<String> getClusterName() {
return clusterName;
}
public void setClusterName(EntityModel<String> clusterName) {
this.clusterName = clusterName;
}
public EntityModel<String> getVolumeName() {
return volumeName;
}
public void setVolumeName(EntityModel<String> volumeName) {
this.volumeName = volumeName;
}
public EntityModel<String> getSnapshotName() {
return snapshotName;
}
public void setSnapshotName(EntityModel<String> snapshotName) {
this.snapshotName = snapshotName;
}
public EntityModel<String> getDescription() {
return description;
}
public void setDescription(EntityModel<String> description) {
this.description = description;
}
public ListModel<GlusterVolumeSnapshotScheduleRecurrence> getRecurrence() {
return recurrence;
}
public void setRecurrence(ListModel<GlusterVolumeSnapshotScheduleRecurrence> recurrence) {
this.recurrence = recurrence;
}
public ListModel<String> getInterval() {
return interval;
}
public void setInterval(ListModel<String> interval) {
this.interval = interval;
}
public ListModel<EndDateOptions> getEndByOptions() {
return endByOptions;
}
public void setEndByOptions(ListModel<EndDateOptions> endByOptions) {
this.endByOptions = endByOptions;
}
public EntityModel<Date> getEndDate() {
return endDate;
}
public void setEndDate(EntityModel<Date> endDate) {
this.endDate = endDate;
}
public boolean isGeneralTabVisible() {
return generalTabVisible;
}
public void setGeneralTabVisible(boolean generalTabVisible) {
this.generalTabVisible = generalTabVisible;
}
public boolean isScheduleTabVisible() {
return scheduleTabVisible;
}
public void setScheduleTabVisible(boolean scheduleTabVisible) {
this.scheduleTabVisible = scheduleTabVisible;
}
public ListModel<Map.Entry<String, String>> getTimeZones() {
return timeZones;
}
public void setTimeZones(ListModel<Map.Entry<String, String>> timeZones) {
this.timeZones = timeZones;
}
public EntityModel<Date> getStartAt() {
return this.startAt;
}
public void setStartAt(EntityModel<Date> value) {
this.startAt = value;
}
public EntityModel<Date> getExecutionTime() {
return this.executionTime;
}
public void setExecutionTime(EntityModel<Date> value) {
this.executionTime = value;
}
public ListModel<List<DayOfWeek>> getDaysOfTheWeek() {
return daysOfWeek;
}
public void setDaysOfTheWeek(ListModel<List<DayOfWeek>> daysOfTheWeek) {
this.daysOfWeek = daysOfTheWeek;
}
public ListModel<String> getDaysOfMonth() {
return daysOfMonth;
}
public void setDaysOfMonth(ListModel<String> daysOfMonth) {
this.daysOfMonth = daysOfMonth;
}
public EntityModel<Boolean> getDisableCliSchedule() {
return this.disableCliSchedule;
}
public void setDisableCliSchedule(EntityModel<Boolean> value) {
this.disableCliSchedule = value;
}
public boolean validate(boolean inplaceValidate) {
String propName;
validateSnapshotName();
validateDaysOfWeek();
validateDaysOfMonth();
validateEndDate();
if (!listenersRegistered) {
initValueChangeListeners();
listenersRegistered = true;
}
if(inplaceValidate) {
propName = "modelPropertiesChanged";//$NON-NLS-1$
} else {
propName = "validateAndSwitchAppropriateTab";//$NON-NLS-1$
}
onPropertyChanged(new PropertyChangedEventArgs(propName));
return getSnapshotName().getIsValid() && getDaysOfTheWeek().getIsValid() && getDaysOfMonth().getIsValid()
&& getDaysOfTheWeek().getIsValid() && getDaysOfMonth().getIsValid() && getEndDate().getIsValid();
}
public enum EndDateOptions {
HasEndDate(ConstantsManager.getInstance().getConstants().endDateOptionText()),
NoEndDate(ConstantsManager.getInstance().getConstants().noEndDateOptionText());
private String description;
private EndDateOptions(String description) {
this.description = description;
}
@Override
public String toString() {
return description;
}
}
}