package ctbrec.variableexpansion;

import static ctbrec.StringUtil.*;
import static java.util.Optional.*;

import java.util.Optional;
import java.util.UUID;

import ctbrec.Config;
import ctbrec.Model;
import ctbrec.ModelGroup;
import ctbrec.StringUtil;
import ctbrec.recorder.Recorder;
import ctbrec.sites.Site;

public class ModelVariableExpander extends AbstractVariableExpander {

    public ModelVariableExpander(Model model, Config config, Recorder recorder) {
        Optional<ModelGroup> modelGroup = Optional.ofNullable(recorder).flatMap(r -> r.getModelGroup(model));
        placeholderValueSuppliers.put("modelName", r -> ofNullable(model.getName()));
        placeholderValueSuppliers.put("modelDisplayName", r -> ofNullable(model.getDisplayName()));
        placeholderValueSuppliers.put("modelSanitizedName", r -> getSanitizedName(model));
        placeholderValueSuppliers.put("modelNotes", r -> getSanitizedModelNotes(config, model));
        placeholderValueSuppliers.put("siteName", r -> ofNullable(model).map(Model::getSite).map(Site::getName));
        placeholderValueSuppliers.put("siteSanitizedName", r -> getSanitizedSiteName(model));
        placeholderValueSuppliers.put("modelGroupName", r -> modelGroup.map(ModelGroup::getName));
        placeholderValueSuppliers.put("modelGroupId", r -> modelGroup.map(ModelGroup::getId).map(UUID::toString));
    }

    public String expand(String input) {
        return fillInPlaceHolders(input, placeholderValueSuppliers);
    }

    private Optional<String> getSanitizedName(Model model) {
        String name = model.getSanitizedNamed();
        if (StringUtil.isBlank(name)) {
            return Optional.empty();
        } else {
            return Optional.of(name);
        }
    }

    private Optional<String> getSanitizedSiteName(Model model) {
        Optional<String> name = ofNullable(model).map(Model::getSite).map(Site::getName);
        if (name.isPresent()) {
            return Optional.of(sanitize(name.get()));
        } else {
            return Optional.empty();
        }
    }

    private Optional<String> getSanitizedModelNotes(Config config, Model m) {
        Optional<String> notes = ofNullable(config.getModelNotes(m));
        if (notes.isPresent()) {
            return Optional.of(sanitize(notes.get()));
        } else {
            return Optional.empty();
        }
    }
}
