/**
 * This code was generated by
 * \ / _    _  _|   _  _
 *  | (_)\/(_)(_|\/| |(/_  v1.0.0
 *       /       /
 */

package com.twilio.rest.insights.v1;

import com.twilio.base.Page;
import com.twilio.base.Reader;
import com.twilio.base.ResourceSet;
import com.twilio.exception.ApiConnectionException;
import com.twilio.exception.ApiException;
import com.twilio.exception.RestException;
import com.twilio.http.HttpMethod;
import com.twilio.http.Request;
import com.twilio.http.Response;
import com.twilio.http.TwilioRestClient;
import com.twilio.rest.Domains;

public class CallSummariesReader extends Reader<CallSummaries> {
    private String from;
    private String to;
    private String fromCarrier;
    private String toCarrier;
    private String fromCountryCode;
    private String toCountryCode;
    private Boolean branded;
    private Boolean verifiedCaller;
    private Boolean hasTag;
    private String startTime;
    private String endTime;
    private String callType;
    private String callState;
    private String direction;
    private CallSummaries.ProcessingStateRequest processingState;
    private CallSummaries.SortBy sortBy;
    private String subaccount;
    private Boolean abnormalSession;

    /**
     * The from.
     *
     * @param from The from
     * @return this
     */
    public CallSummariesReader setFrom(final String from) {
        this.from = from;
        return this;
    }

    /**
     * The to.
     *
     * @param to The to
     * @return this
     */
    public CallSummariesReader setTo(final String to) {
        this.to = to;
        return this;
    }

    /**
     * The from_carrier.
     *
     * @param fromCarrier The from_carrier
     * @return this
     */
    public CallSummariesReader setFromCarrier(final String fromCarrier) {
        this.fromCarrier = fromCarrier;
        return this;
    }

    /**
     * The to_carrier.
     *
     * @param toCarrier The to_carrier
     * @return this
     */
    public CallSummariesReader setToCarrier(final String toCarrier) {
        this.toCarrier = toCarrier;
        return this;
    }

    /**
     * The from_country_code.
     *
     * @param fromCountryCode The from_country_code
     * @return this
     */
    public CallSummariesReader setFromCountryCode(final String fromCountryCode) {
        this.fromCountryCode = fromCountryCode;
        return this;
    }

    /**
     * The to_country_code.
     *
     * @param toCountryCode The to_country_code
     * @return this
     */
    public CallSummariesReader setToCountryCode(final String toCountryCode) {
        this.toCountryCode = toCountryCode;
        return this;
    }

    /**
     * The branded.
     *
     * @param branded The branded
     * @return this
     */
    public CallSummariesReader setBranded(final Boolean branded) {
        this.branded = branded;
        return this;
    }

    /**
     * The verified_caller.
     *
     * @param verifiedCaller The verified_caller
     * @return this
     */
    public CallSummariesReader setVerifiedCaller(final Boolean verifiedCaller) {
        this.verifiedCaller = verifiedCaller;
        return this;
    }

    /**
     * The has_tag.
     *
     * @param hasTag The has_tag
     * @return this
     */
    public CallSummariesReader setHasTag(final Boolean hasTag) {
        this.hasTag = hasTag;
        return this;
    }

    /**
     * The start_time.
     *
     * @param startTime The start_time
     * @return this
     */
    public CallSummariesReader setStartTime(final String startTime) {
        this.startTime = startTime;
        return this;
    }

    /**
     * The end_time.
     *
     * @param endTime The end_time
     * @return this
     */
    public CallSummariesReader setEndTime(final String endTime) {
        this.endTime = endTime;
        return this;
    }

    /**
     * The call_type.
     *
     * @param callType The call_type
     * @return this
     */
    public CallSummariesReader setCallType(final String callType) {
        this.callType = callType;
        return this;
    }

    /**
     * The call_state.
     *
     * @param callState The call_state
     * @return this
     */
    public CallSummariesReader setCallState(final String callState) {
        this.callState = callState;
        return this;
    }

    /**
     * The direction.
     *
     * @param direction The direction
     * @return this
     */
    public CallSummariesReader setDirection(final String direction) {
        this.direction = direction;
        return this;
    }

    /**
     * The processing_state.
     *
     * @param processingState The processing_state
     * @return this
     */
    public CallSummariesReader setProcessingState(final CallSummaries.ProcessingStateRequest processingState) {
        this.processingState = processingState;
        return this;
    }

    /**
     * The sort_by.
     *
     * @param sortBy The sort_by
     * @return this
     */
    public CallSummariesReader setSortBy(final CallSummaries.SortBy sortBy) {
        this.sortBy = sortBy;
        return this;
    }

    /**
     * The subaccount.
     *
     * @param subaccount The subaccount
     * @return this
     */
    public CallSummariesReader setSubaccount(final String subaccount) {
        this.subaccount = subaccount;
        return this;
    }

    /**
     * The abnormal_session.
     *
     * @param abnormalSession The abnormal_session
     * @return this
     */
    public CallSummariesReader setAbnormalSession(final Boolean abnormalSession) {
        this.abnormalSession = abnormalSession;
        return this;
    }

    /**
     * Make the request to the Twilio API to perform the read.
     *
     * @param client TwilioRestClient with which to make the request
     * @return CallSummaries ResourceSet
     */
    @Override
    public ResourceSet<CallSummaries> read(final TwilioRestClient client) {
        return new ResourceSet<>(this, client, firstPage(client));
    }

    /**
     * Make the request to the Twilio API to perform the read.
     *
     * @param client TwilioRestClient with which to make the request
     * @return CallSummaries ResourceSet
     */
    @Override
    @SuppressWarnings("checkstyle:linelength")
    public Page<CallSummaries> firstPage(final TwilioRestClient client) {
        Request request = new Request(
            HttpMethod.GET,
            Domains.INSIGHTS.toString(),
            "/v1/Voice/Summaries"
        );

        addQueryParams(request);
        return pageForRequest(client, request);
    }

    /**
     * Retrieve the target page from the Twilio API.
     *
     * @param targetUrl API-generated URL for the requested results page
     * @param client TwilioRestClient with which to make the request
     * @return CallSummaries ResourceSet
     */
    @Override
    @SuppressWarnings("checkstyle:linelength")
    public Page<CallSummaries> getPage(final String targetUrl, final TwilioRestClient client) {
        Request request = new Request(
            HttpMethod.GET,
            targetUrl
        );

        return pageForRequest(client, request);
    }

    /**
     * Retrieve the next page from the Twilio API.
     *
     * @param page current page
     * @param client TwilioRestClient with which to make the request
     * @return Next Page
     */
    @Override
    public Page<CallSummaries> nextPage(final Page<CallSummaries> page,
                                        final TwilioRestClient client) {
        Request request = new Request(
            HttpMethod.GET,
            page.getNextPageUrl(Domains.INSIGHTS.toString())
        );
        return pageForRequest(client, request);
    }

    /**
     * Retrieve the previous page from the Twilio API.
     *
     * @param page current page
     * @param client TwilioRestClient with which to make the request
     * @return Previous Page
     */
    @Override
    public Page<CallSummaries> previousPage(final Page<CallSummaries> page,
                                            final TwilioRestClient client) {
        Request request = new Request(
            HttpMethod.GET,
            page.getPreviousPageUrl(Domains.INSIGHTS.toString())
        );
        return pageForRequest(client, request);
    }

    /**
     * Generate a Page of CallSummaries Resources for a given request.
     *
     * @param client TwilioRestClient with which to make the request
     * @param request Request to generate a page for
     * @return Page for the Request
     */
    private Page<CallSummaries> pageForRequest(final TwilioRestClient client, final Request request) {
        Response response = client.request(request);

        if (response == null) {
            throw new ApiConnectionException("CallSummaries read failed: Unable to connect to server");
        } else if (!TwilioRestClient.SUCCESS.test(response.getStatusCode())) {
            RestException restException = RestException.fromJson(response.getStream(), client.getObjectMapper());
            if (restException == null) {
                throw new ApiException("Server Error, no content");
            }
           throw new ApiException(restException);
        }

        return Page.fromJson(
            "call_summaries",
            response.getContent(),
            CallSummaries.class,
            client.getObjectMapper()
        );
    }

    /**
     * Add the requested query string arguments to the Request.
     *
     * @param request Request to add query string arguments to
     */
    private void addQueryParams(final Request request) {
        if (from != null) {
            request.addQueryParam("From", from);
        }

        if (to != null) {
            request.addQueryParam("To", to);
        }

        if (fromCarrier != null) {
            request.addQueryParam("FromCarrier", fromCarrier);
        }

        if (toCarrier != null) {
            request.addQueryParam("ToCarrier", toCarrier);
        }

        if (fromCountryCode != null) {
            request.addQueryParam("FromCountryCode", fromCountryCode);
        }

        if (toCountryCode != null) {
            request.addQueryParam("ToCountryCode", toCountryCode);
        }

        if (branded != null) {
            request.addQueryParam("Branded", branded.toString());
        }

        if (verifiedCaller != null) {
            request.addQueryParam("VerifiedCaller", verifiedCaller.toString());
        }

        if (hasTag != null) {
            request.addQueryParam("HasTag", hasTag.toString());
        }

        if (startTime != null) {
            request.addQueryParam("StartTime", startTime);
        }

        if (endTime != null) {
            request.addQueryParam("EndTime", endTime);
        }

        if (callType != null) {
            request.addQueryParam("CallType", callType);
        }

        if (callState != null) {
            request.addQueryParam("CallState", callState);
        }

        if (direction != null) {
            request.addQueryParam("Direction", direction);
        }

        if (processingState != null) {
            request.addQueryParam("ProcessingState", processingState.toString());
        }

        if (sortBy != null) {
            request.addQueryParam("SortBy", sortBy.toString());
        }

        if (subaccount != null) {
            request.addQueryParam("Subaccount", subaccount);
        }

        if (abnormalSession != null) {
            request.addQueryParam("AbnormalSession", abnormalSession.toString());
        }

        if (getPageSize() != null) {
            request.addQueryParam("PageSize", Integer.toString(getPageSize()));
        }
    }
}