package de.ivu.elect.business.konfiguration.control;

import de.ivu.elect.jee.faces.FacesMessageUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;


public class FileExistsValidator implements Validator {
  private static final Logger LOG = LoggerFactory.getLogger(FileExistsValidator.class);

  private static final String FILE_NOT_FOUND = "file.not.found";
  private static final String FILE_MUST_BE_SPECIFIED = "file.must.be.specified";

  public enum Mode {
    ALLOW_EMPTY,
    MUST_BE_SET
  }

  private final Mode mode;

  public FileExistsValidator(Mode mode) {
    this.mode = mode;
  }

  @Override
  public void validate(FacesContext context, UIComponent component, Object value)
      throws ValidatorException {
    String pathToFile = (String) value;

    if (StringUtils.isEmpty(pathToFile) && isAllowEmpty()) {
      return;
    } else if (StringUtils.isEmpty(pathToFile)) {
      throw new ValidatorException(createErrorMessage(context, pathToFile, FILE_MUST_BE_SPECIFIED));
    }

    try (InputStream is = openFile(pathToFile)) {
      // Just trying to open file
    } catch (FileNotFoundException e) {
      throw new ValidatorException(createErrorMessage(context, pathToFile, FILE_NOT_FOUND), e);
    } catch (IOException e) {
      LOG.error("Unexpected error when closing the file stream", e);
    }
  }

  boolean isAllowEmpty() {
    return Mode.ALLOW_EMPTY.equals(mode);
  }

  InputStream openFile(String pathToFile) throws FileNotFoundException {
    return new FileInputStream(pathToFile);
  }

  FacesMessage createErrorMessage(FacesContext context, String pathToFile, String key) {
    return FacesMessageUtil.createErrorMessage(context, key, key, pathToFile);
  }
}
