package ru.yandex.autotests.directapi.apiclient.version4;

import ru.yandex.autotests.directapi.apiclient.BaseApiClient;
import ru.yandex.autotests.directapi.apiclient.RequestHeader;
import ru.yandex.autotests.directapi.apiclient.config.ConnectionConfig;
import ru.yandex.autotests.directapi.apiclient.methods.Method;
import ru.yandex.autotests.directapi.model.User;

import static ru.yandex.autotests.irt.testutils.json.JsonUtils.move;

/**
 * Author pavryabov
 * Date 30.06.14
 */
public abstract class BaseApiV4Client extends BaseApiClient {

    public abstract <T> T invokeMethod(String methodName, Object params);

    /**
     * Initialized with default properties
     */
    public BaseApiV4Client() {
        super();
    }

    public BaseApiV4Client(ConnectionConfig connectionConfig) {
        super(connectionConfig);
    }

    public BaseApiV4Client(ConnectionConfig connectionConfig, RequestHeader requestHeader) {
        super(connectionConfig, requestHeader);
    }

    public int getVersion() {
        return connectionConfig.getAPIVersion();
    }

    public <T> T invokeMethod(Method methodName, Object params) {
        return invokeMethod(methodName.toString(), params);
    }

    public <T extends BaseApiV4Client> T auth(String login) {
        return auth(User.get(login));
    }

    public <T extends BaseApiV4Client> T auth(User account) {
        this.requestHeader = new RequestHeader(account);
        return (T) this;
    }

    public <T extends BaseApiV4Client> T version(int version) {
        connectionConfig.version(version);
        return (T) this;
    }

    /**
     * Use .version(version).wsdl(API_PortType) instead
     *
     * @param version
     * @param clientType
     * @param <T>
     * @return
     */
    @Deprecated
    public <T extends BaseApiV4Client> T version(int version, Class<T> clientType) {
        connectionConfig.apiPortType(clientType);
        connectionConfig.version(version);
        return (T) this;
    }

    public <T extends BaseApiV4Client> T wsdl(Class<?> clientType) {
        connectionConfig.apiPortType(clientType);
        return (T) this;
    }

    public <T extends BaseApiV4Client> T connect(ConnectionConfig config) {
        this.connectionConfig = config;
        return (T) this;
    }

    public <T extends BaseApiV4Client> T connect(String endPoint) {
        this.connectionConfig.url(endPoint);
        return (T) this;
    }

    public String getPackageName() {
        return connectionConfig.getPackage();
    }

    public <T> T toRequestType(Object original) {
        return move(original, getPackageName());
    }
}
