// Path: src/main/java/com/github/vedenin/codingchallenge/common/CurrencyEnum.java
// public enum CurrencyEnum {
//     EUR("EUR", "Euro (EUR)"),
//     USD("USD", "US Dollar (USD)"),
//     GBP("GBP", "British Pound (GBP)"),
//     NZD("NZD", "New Zealand Dollar (NZD)"),
//     AUD("AUD", "Australian Dollar (AUD)"),
//     JPY("JPY", "Japanese Yen (JPY)"),
//     HUF("HUF", "Hungarian Forint (HUF)"),
//     RUB("RUB", "Russian Ruble (RUB)"),
//     PLN("PLN", "Polish Zloty (PLN)");
//     private final String code;
//     private final String description;
// 
//     CurrencyEnum(String code, String description) {
//         this.code = code;
//         this.description = description;
//     }
// 
//     public String getCode() {
//         return code;
//     }
// 
//     public String getDescription() {
//         return description;
//     }
// }
// 
// Path: src/main/java/com/github/vedenin/codingchallenge/converter/CurrencyConvector.java
// public interface CurrencyConvector {
//     BigDecimal getConvertingValue(Boolean isHistory, BigDecimal amount, CurrencyEnum currencyFrom,
//                                   CurrencyEnum currencyTo, Calendar calendar);
// }
// 
// Path: src/main/java/com/github/vedenin/codingchallenge/converter/DateConverter.java
// public interface DateConverter {
//     Calendar getCalendarFromString(String date);
// }
// 
// Path: src/main/java/com/github/vedenin/codingchallenge/mvc/model/ConverterFormModel.java
// public class ConverterFormModel {
//     @NotNull
//     private String to = CurrencyEnum.USD.getCode();
//     @NotNull
//     private String from = CurrencyEnum.EUR.getCode();
//     @Min(0)
//     @NotNull
//     private BigDecimal amount = new BigDecimal(0.0);
// 
//     private String type = "current";
// 
//     private String date = "";
// 
//     public String getTo() {
//         return to;
//     }
// 
//     public void setTo(String to) {
//         this.to = to;
//     }
// 
//     public String getFrom() {
//         return from;
//     }
// 
//     public void setFrom(String from) {
//         this.from = from;
//     }
// 
//     public BigDecimal getAmount() {
//         return amount;
//     }
// 
//     public void setAmount(BigDecimal amount) {
//         this.amount = amount;
//     }
// 
//     public CurrencyEnum getCurrencyEnumTo() {
//         return Enum.valueOf(CurrencyEnum.class, to);
//     }
// 
//     public CurrencyEnum getCurrencyEnumFrom() {
//         return Enum.valueOf(CurrencyEnum.class, from);
//     }
// 
//     public String getType() {
//         return type;
//     }
// 
//     public Boolean isHistory() {
//         return type.equals("history");
//     }
//     public void setType(String type) {
//         this.type = type;
//     }
// 
//     public String getDate() {
//         return date;
//     }
// 
//     public void setDate(String date) {
//         this.date = date;
//     }
// 
//     @AssertTrue
//     public boolean isDataCorrect() {
//         return type.equals("current") || !date.isEmpty();
//     }
// }
// 
// Path: src/main/java/com/github/vedenin/codingchallenge/mvc/model/CountryService.java
// public interface CountryService {
//     List<String> getCountriesNames();
// }
// 
// Path: src/main/java/com/github/vedenin/codingchallenge/mvc/Consts.java
// public final class Consts {
//     public static final String CONVERTER_URL = "converter";
//     public static final String LOGIN_URL = "login";
//     public static final String REGISTER_URL = "register";
// }


import com.github.vedenin.codingchallenge.common.CurrencyEnum;
import com.github.vedenin.codingchallenge.converter.CurrencyConvector;
import com.github.vedenin.codingchallenge.converter.DateConverter;
import com.github.vedenin.codingchallenge.mvc.model.ConverterFormModel;
import com.github.vedenin.codingchallenge.mvc.model.CountryService;
import com.github.vedenin.codingchallenge.persistence.*;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.math.BigDecimal;
import java.util.Date;
import javax.inject.Inject;
import static com.github.vedenin.codingchallenge.mvc.Consts.*;
            } else {
                model.addAttribute("countires", countryService.getCountriesNames());
                return REGISTER_URL;
            }
        } catch (Exception exp) {
            model.addAttribute("error", exp.getMessage());
            return REGISTER_URL;
        }
    }


    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName(LOGIN_URL);
        registry.addViewController("/" + LOGIN_URL).setViewName(LOGIN_URL);
    }

    @ExceptionHandler(Exception.class)
    public String handleError(Model model, Exception ex) {
        errorRepository.save(new ErrorEntity("Error in MVC service", ex));
        model.addAttribute("error", ex.getMessage());
        return CONVERTER_URL;
    }

    private void saveQuery(ConverterFormModel converterFormModel, BigDecimal result) {
        historyRepository.save(new HistoryEntity(converterFormModel.getAmount(),
                converterFormModel.getCurrencyEnumFrom(), converterFormModel.getCurrencyEnumTo(),
                new Date(), result, converterFormModel.getType(), converterFormModel.getDate()));
    }

// Path: src/main/java/com/github/vedenin/codingchallenge/common/CurrencyEnum.java
// public enum CurrencyEnum {
//     EUR("EUR", "Euro (EUR)"),
//     USD("USD", "US Dollar (USD)"),
//     GBP("GBP", "British Pound (GBP)"),
//     NZD("NZD", "New Zealand Dollar (NZD)"),
//     AUD("AUD", "Australian Dollar (AUD)"),
//     JPY("JPY", "Japanese Yen (JPY)"),
//     HUF("HUF", "Hungarian Forint (HUF)"),
//     RUB("RUB", "Russian Ruble (RUB)"),
//     PLN("PLN", "Polish Zloty (PLN)");
//     private final String code;
//     private final String description;
// 
//     CurrencyEnum(String code, String description) {
//         this.code = code;
//         this.description = description;
//     }
// 
//     public String getCode() {
//         return code;
//     }
// 
//     public String getDescription() {
//         return description;
//     }
// }
// 
// Path: src/main/java/com/github/vedenin/codingchallenge/converter/CurrencyConvector.java
// public interface CurrencyConvector {
//     BigDecimal getConvertingValue(Boolean isHistory, BigDecimal amount, CurrencyEnum currencyFrom,
//                                   CurrencyEnum currencyTo, Calendar calendar);
// }
// 
// Path: src/main/java/com/github/vedenin/codingchallenge/converter/DateConverter.java
// public interface DateConverter {
//     Calendar getCalendarFromString(String date);
// }
// 
// Path: src/main/java/com/github/vedenin/codingchallenge/mvc/model/ConverterFormModel.java
// public class ConverterFormModel {
//     @NotNull
//     private String to = CurrencyEnum.USD.getCode();
//     @NotNull
//     private String from = CurrencyEnum.EUR.getCode();
//     @Min(0)
//     @NotNull
//     private BigDecimal amount = new BigDecimal(0.0);
// 
//     private String type = "current";
// 
//     private String date = "";
// 
//     public String getTo() {
//         return to;
//     }
// 
//     public void setTo(String to) {
//         this.to = to;
//     }
// 
//     public String getFrom() {
//         return from;
//     }
// 
//     public void setFrom(String from) {
//         this.from = from;
//     }
// 
//     public BigDecimal getAmount() {
//         return amount;
//     }
// 
//     public void setAmount(BigDecimal amount) {
//         this.amount = amount;
//     }
// 
//     public CurrencyEnum getCurrencyEnumTo() {
//         return Enum.valueOf(CurrencyEnum.class, to);
//     }
// 
//     public CurrencyEnum getCurrencyEnumFrom() {
//         return Enum.valueOf(CurrencyEnum.class, from);
//     }
// 
//     public String getType() {
//         return type;
//     }
// 
//     public Boolean isHistory() {
//         return type.equals("history");
//     }
//     public void setType(String type) {
//         this.type = type;
//     }
// 
//     public String getDate() {
//         return date;
//     }
// 
//     public void setDate(String date) {
//         this.date = date;
//     }
// 
//     @AssertTrue
//     public boolean isDataCorrect() {
//         return type.equals("current") || !date.isEmpty();
//     }
// }
// 
// Path: src/main/java/com/github/vedenin/codingchallenge/mvc/model/CountryService.java
// public interface CountryService {
//     List<String> getCountriesNames();
// }
// 
// Path: src/main/java/com/github/vedenin/codingchallenge/mvc/Consts.java
// public final class Consts {
//     public static final String CONVERTER_URL = "converter";
//     public static final String LOGIN_URL = "login";
//     public static final String REGISTER_URL = "register";
// }


// Path: src/main/java/com/github/vedenin/codingchallenge/mvc/controler/MainWebController.java
import com.github.vedenin.codingchallenge.common.CurrencyEnum;
import com.github.vedenin.codingchallenge.converter.CurrencyConvector;
import com.github.vedenin.codingchallenge.converter.DateConverter;
import com.github.vedenin.codingchallenge.mvc.model.ConverterFormModel;
import com.github.vedenin.codingchallenge.mvc.model.CountryService;
import com.github.vedenin.codingchallenge.persistence.*;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.math.BigDecimal;
import java.util.Date;
import javax.inject.Inject;
import static com.github.vedenin.codingchallenge.mvc.Consts.*;

            } else {
                model.addAttribute("countires", countryService.getCountriesNames());
                return REGISTER_URL;
            }
        } catch (Exception exp) {
            model.addAttribute("error", exp.getMessage());
            return REGISTER_URL;
        }
    }


    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName(LOGIN_URL);
        registry.addViewController("/" + LOGIN_URL).setViewName(LOGIN_URL);
    }

    @ExceptionHandler(Exception.class)
    public String handleError(Model model, Exception ex) {
        errorRepository.save(new ErrorEntity("Error in MVC service", ex));
        model.addAttribute("error", ex.getMessage());
        return CONVERTER_URL;
    }

    private void saveQuery(ConverterFormModel converterFormModel, BigDecimal result) {
        historyRepository.save(new HistoryEntity(converterFormModel.getAmount(),
                converterFormModel.getCurrencyEnumFrom(), converterFormModel.getCurrencyEnumTo(),
                new Date(), result, converterFormModel.getType(), converterFormModel.getDate()));
    }

    private BigDecimal getResult(ConverterFormModel converterFormModel) {