/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.ov.mixing.commons.configuration;

import static java.util.Objects.requireNonNull;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.MapType;
import com.fasterxml.jackson.databind.type.TypeFactory;

public class BGParamsProvider {

    private static final Logger LOG = LoggerFactory.getLogger("std");

    private final Map<Integer, BGParams> size2Params;

    public BGParamsProvider() {

        try (InputStream in = getClass().getResourceAsStream("/bGParams.json")) {

            ObjectMapper mapper = new ObjectMapper();

            TypeFactory typeFactory = mapper.getTypeFactory();
            MapType type = typeFactory.constructMapType(HashMap.class, Integer.class, BGParams.class);

            size2Params = mapper.readValue(in, type);

        } catch (IOException e) {
            throw new IllegalStateException("An error occured while attempting to read the bGParamsProviderPath file: " + e);
        }
    }
    
    public BGParamsProvider(Map<Integer, BGParams> paramsMapping) {
        requireNonNull(paramsMapping, "Params mapping is null.");
        this.size2Params = new HashMap<>(paramsMapping);
    }

    public BGParams getParamsForGiven(final int partitionSize) {

        BGParams bgParams = size2Params.get(partitionSize);

        if (bgParams == null) {

            LOG.warn("Best config parameters NOT FOUND for partitionSize = '" + partitionSize
                    + "' on bGParams.json file, using default values...");
            return createDefaultBGParams(partitionSize);
        } else {

            LOG.info("Best config parameters FOUND for partitionSize = '" + partitionSize
                + "' on bGParams.json file, using these values..." + bgParams);
            return bgParams;
        }
    }

    private static BGParams createDefaultBGParams(final int partitionSize) {

        BGParams bgParams = new BGParams();
        bgParams.setM(1);
        bgParams.setN(partitionSize);
        bgParams.setMu(2);
        bgParams.setNumIterations(0);
        return bgParams;
    }
}
