import DatabaseProperty from "../Database/DatabaseProperty";
import BadDataException from "../Exception/BadDataException";
import { ObjectType } from "../JSON";
export default class Route extends DatabaseProperty {
    get route() {
        return this._route;
    }
    set route(v) {
        const matchRouteCharacters = /^[a-zA-Z_\d\-!#$%&'()*+,./:;=?@[\]]*$/;
        if (v && !matchRouteCharacters.test(v)) {
            throw new BadDataException(`Invalid route: ${v}`);
        }
        this._route = v;
    }
    constructor(route) {
        super();
        this._route = "";
        if (route && route instanceof Route) {
            route = route.toString();
        }
        route = route === null || route === void 0 ? void 0 : route.replace(/\/+/g, "/"); // remove multiple slashes from route and replace with single slash
        if (route) {
            this.route = route;
        }
    }
    toJSON() {
        return {
            _type: ObjectType.Route,
            value: this.toString(),
        };
    }
    static fromJSON(json) {
        if (json["_type"] === ObjectType.Route) {
            return new Route(json["value"] || "");
        }
        throw new BadDataException("Invalid JSON: " + JSON.stringify(json));
    }
    addRoute(route) {
        route = route.toString();
        if (!route.startsWith("/")) {
            route = "/" + route;
        }
        if (typeof route === "string") {
            route = new Route(route);
        }
        let routeToBeAdded = route.toString();
        if (this.route.endsWith("/") && routeToBeAdded.trim().startsWith("/")) {
            routeToBeAdded = routeToBeAdded.trim().substring(1); // remove leading  "/" from route
        }
        this.route = new Route(this.route + routeToBeAdded).route;
        return this;
    }
    toString() {
        return this.route;
    }
    static fromString(route) {
        return new Route(route);
    }
    addRouteParam(paramName, value) {
        this.route = this.route.replace(paramName, value);
        return this;
    }
    static toDatabase(value) {
        if (value) {
            if (typeof value === "string") {
                value = new Route(value);
            }
            return value.toString();
        }
        return value;
    }
    static fromDatabase(_value) {
        if (_value) {
            return new Route(_value);
        }
        return null;
    }
    addQueryParams(queryParams) {
        // make sure route ends with "?" if it doesn't have any query params
        if (!this.route.includes("?")) {
            this.route += "?";
        }
        for (const key in queryParams) {
            this.route += `${key}=${queryParams[key]}&`;
        }
        //remove last "&" from route
        this.route = this.route.substring(0, this.route.length - 1);
        return this;
    }
}
//# sourceMappingURL=Route.js.map