/*
 * Copyright (c) eHealth
 */
package be.fgov.ehealth.technicalconnector.tests.server;


import be.fgov.ehealth.technicalconnector.tests.server.asserter.HttpAsserter;
import be.fgov.ehealth.technicalconnector.tests.server.callback.*;
import org.mockserver.integration.ClientAndServer;
import org.mockserver.mock.action.ExpectationCallback;

import java.util.HashMap;
import java.util.Map;

import static org.apache.commons.lang3.StringUtils.startsWith;
import static org.mockserver.integration.ClientAndServer.startClientAndServer;
import static org.mockserver.model.HttpRequest.request;

public class HttpServerStub {

    private Map<String, ExpectationCallback> callbackMap = new HashMap<String, ExpectationCallback>();

    private static ClientAndServer mockClient;
    private int port;

    public HttpServerStub(int port) throws Exception {
        mockClient = startClientAndServer(port);
        this.port = port;
    }

    public void shutdown() {
        mockClient.stop(true);
    }
    
    public void reset() {
    	mockClient.reset();
    }


    public void add(String path, String content) {
        if (callbackMap.containsKey(path)) {
            ExpectationCallback callback = callbackMap.get(path);
            if (callback instanceof ContentExpectationCallback) {
                ((ContentExpectationCallback) callback).add(content);
            }
            if (callback instanceof FullExpectationCallback) {
                ((FullExpectationCallback) callback).add(content);
            }
        } else {
            ExpectationCallback callback;
            if (startsWith(path, "/echo")) {
                callback = new EchoExpectationCallback();
            } else if (startsWith(path, "/error")) {
                callback = new ErrorExpectationCallback();
            } else if (startsWith(path, "/timeout")) {
                callback = new TimeOutExpectationCallback();
            } else if (startsWith(path, "/full")) {
                callback = new FullExpectationCallback();
                ((FullExpectationCallback) callback).add(content);
            } else {
                callback = new ContentExpectationCallback();
                ((ContentExpectationCallback) callback).add(content);
            }

            register(path, callback);
        }
    }

    private void register(String path, ExpectationCallback callback) {
        callbackMap.put(path, callback);
        mockClient.when(request()
                .withPath(path))
                .callback(callback);
    }

    public void add(String path, HttpAsserter asserter) {
        if (startsWith(path, "/assert")) {
            register(path, new AssertExpectationCallback(asserter));
            return;
        }
        throw new IllegalArgumentException("Unsupported url pattern [" + path + "]");

    }

    @Override
    public String toString() {
        return "HttpServerStub{" +
                "callbackMap=" + callbackMap.keySet() +
                ", port=" + port +
                '}';
    }
}
