import { SerializablePayload } from './SerializablePayload.js';
import { HeadersArray } from './HeadersArray.js';
export const Kind = 'Core#HttpRequest';
/**
 * The base model of an HTTP request.
 *
 * **Note about the payload.**
 *
 * The payload is **always** stored in the request object in its serialized form.
 * Use the `readPayload()` to read the correct data type and the `writePayload()` to
 * safely store the payload.
 */
export class HttpRequest extends SerializablePayload {
    kind = Kind;
    /**
     * The request URL
     */
    url = '';
    /**
     * HTTP method name.
     * Defaults to "GET".
     */
    method = 'GET';
    /**
     * HTTP headers string
     */
    headers;
    /**
     * Headers model, if any.
     * When reading headers string, the value of `headers` is preferred over the model.
     */
    headersModel;
    static fromBaseValues(values) {
        return new HttpRequest({
            ...values,
            kind: Kind,
        });
    }
    /**
     * @param input The request definition used to restore the state.
     */
    constructor(input) {
        super();
        let init;
        if (typeof input === 'string') {
            init = JSON.parse(input);
        }
        else if (typeof input === 'object') {
            init = input;
        }
        else {
            init = {
                kind: Kind,
                url: '',
                method: 'GET',
            };
        }
        this.new(init);
    }
    /**
     * Creates a new request clearing anything that is so far defined.
     *
     * Note, this throws an error when the object is not a request.
     */
    new(init) {
        const { url, method = 'GET', headers, payload, kind = Kind, headersModel, payloadOptions } = init;
        this.kind = kind;
        this.url = url;
        this.method = method;
        this.headers = headers;
        this.payload = payload;
        if (Array.isArray(headersModel)) {
            this.headersModel = HeadersArray.from(headersModel);
        }
        else {
            this.headersModel = undefined;
        }
        if (payloadOptions) {
            this.payloadOptions = payloadOptions;
        }
        else {
            this.payloadOptions = undefined;
        }
    }
    /**
     * Checks whether the input is a definition of an HTTP request.
     */
    static isHttpRequest(input) {
        const typed = input;
        if (!input || typed.kind !== Kind) {
            return false;
        }
        return true;
    }
    toJSON() {
        const result = {
            ...super.toJSON(),
            kind: this.kind,
            url: this.url,
            method: this.method,
        };
        if (this.headers) {
            result.headers = this.headers;
        }
        if (this.headersModel) {
            result.headersModel = this.headersModel.toJSON();
        }
        return result;
    }
    /**
     * It reads headers from the request.
     * It prefers `headers` string over `headersModel` so set only the model
     * if the application should only use model.
     * @returns The HTTP headers string from the current headers.
     */
    toHeadersString() {
        const { headers, headersModel } = this;
        if (headers) {
            return headers;
        }
        if (headersModel) {
            return headersModel.toString();
        }
        return '';
    }
}
//# sourceMappingURL=HttpRequest.js.map