import { pageExtract, projectListExtract, unwrapOrgResponse, unwrapProjectResponse } from "../extractors.js";
import { stripNulls } from "../../utils/body-normalizer.js";
// ---------------------------------------------------------------------------
// Body schemas (for harness_describe output)
// ---------------------------------------------------------------------------
const orgCreateSchema = {
    description: "Organization definition",
    fields: [
        { name: "identifier", type: "string", required: true, description: "Unique identifier (lowercase, hyphens, underscores)" },
        { name: "name", type: "string", required: true, description: "Display name" },
        { name: "description", type: "string", required: false, description: "Optional description" },
        { name: "tags", type: "object", required: false, description: "Key-value tag map" },
    ],
};
const orgUpdateSchema = {
    description: "Organization update definition",
    fields: [
        { name: "identifier", type: "string", required: false, description: "Identifier (auto-injected from org_id if missing)" },
        { name: "name", type: "string", required: true, description: "Display name" },
        { name: "description", type: "string", required: false, description: "Updated description" },
        { name: "tags", type: "object", required: false, description: "Key-value tag map" },
    ],
};
const projectCreateSchema = {
    description: "Project definition",
    fields: [
        { name: "identifier", type: "string", required: true, description: "Unique identifier (lowercase, hyphens, underscores)" },
        { name: "name", type: "string", required: true, description: "Display name" },
        { name: "description", type: "string", required: false, description: "Optional description" },
        { name: "color", type: "string", required: false, description: "Project color (hex code)" },
        { name: "modules", type: "array", required: false, description: "Enabled modules (CD, CI, CF, CE, CV, STO, CHAOS, SRM, IACM, CET, CODE, IDP, SSCA, SEI)" },
        { name: "tags", type: "object", required: false, description: "Key-value tag map" },
    ],
};
const projectUpdateSchema = {
    description: "Project update definition",
    fields: [
        { name: "identifier", type: "string", required: false, description: "Identifier (auto-injected from project_id if missing)" },
        { name: "name", type: "string", required: true, description: "Display name" },
        { name: "description", type: "string", required: false, description: "Updated description" },
        { name: "color", type: "string", required: false, description: "Project color (hex code)" },
        { name: "modules", type: "array", required: false, description: "Enabled modules" },
        { name: "tags", type: "object", required: false, description: "Key-value tag map" },
    ],
};
// ---------------------------------------------------------------------------
// Body builders for v1 API wrapper format
// ---------------------------------------------------------------------------
/**
 * Build org body: NG `/ng/api/organizations` expects `{ organization: { identifier, name, ... } }`.
 * Accepts `{ organization: {...} }`, legacy `{ org: {...} }`, or flat `{ identifier, name, ... }`.
 */
function buildOrgBody(input) {
    const body = input.body;
    if (!body || typeof body !== "object")
        return undefined;
    const rec = body;
    if ("organization" in rec && typeof rec.organization === "object" && rec.organization !== null) {
        return stripNulls({ organization: rec.organization });
    }
    if ("org" in rec && typeof rec.org === "object" && rec.org !== null) {
        return stripNulls({ organization: rec.org });
    }
    return stripNulls({ organization: rec });
}
/**
 * Build org update body: same as create, but injects identifier from org_id if missing.
 */
function buildOrgUpdateBody(input) {
    const body = input.body;
    if (!body || typeof body !== "object")
        return undefined;
    const rec = body;
    let inner;
    if ("organization" in rec && typeof rec.organization === "object" && rec.organization !== null) {
        inner = { ...rec.organization };
    }
    else if ("org" in rec && typeof rec.org === "object" && rec.org !== null) {
        inner = { ...rec.org };
    }
    else {
        inner = { ...rec };
    }
    // Inject identifier from path param if missing
    if (!inner.identifier && input.org_id) {
        inner.identifier = input.org_id;
    }
    return stripNulls({ organization: inner });
}
/**
 * Build project body: v1 API expects `{ project: { identifier, name, ... } }`.
 * Accepts either `{ project: {...} }` (pass-through) or `{ identifier, name, ... }` (auto-wrap).
 */
function buildProjectBody(input) {
    const body = input.body;
    if (!body || typeof body !== "object")
        return undefined;
    const rec = body;
    // Already wrapped — use as-is
    if ("project" in rec && typeof rec.project === "object") {
        return stripNulls(rec);
    }
    // Wrap flat fields
    return stripNulls({ project: rec });
}
/**
 * Build project update body: same as create, but injects identifier from project_id if missing.
 */
function buildProjectUpdateBody(input) {
    const body = input.body;
    if (!body || typeof body !== "object")
        return undefined;
    const rec = body;
    let inner;
    if ("project" in rec && typeof rec.project === "object" && rec.project !== null) {
        inner = { ...rec.project };
    }
    else {
        inner = { ...rec };
    }
    // Inject identifier from path param if missing
    if (!inner.identifier && input.project_id) {
        inner.identifier = input.project_id;
    }
    return stripNulls({ project: inner });
}
// ---------------------------------------------------------------------------
// Toolset definition
// ---------------------------------------------------------------------------
export const platformToolset = {
    name: "platform",
    displayName: "Platform",
    description: "Harness platform entities — organizations and projects",
    resources: [
        // ----- Organization -----
        {
            resourceType: "organization",
            displayName: "Organization",
            description: "Harness organization. Top-level grouping under an account. Supports full CRUD via v1 API.",
            toolset: "platform",
            scope: "account",
            identifierFields: ["org_id"],
            listFilterFields: [
                { name: "search_term", description: "Filter organizations by name, ID, or tags (maps to searchTerm)" },
                { name: "identifiers", description: "Comma-separated org identifiers to fetch specific orgs" },
                { name: "sort_orders", description: "Sort criteria (maps to sortOrders), e.g. fieldName=name&orderType=ASC" },
                { name: "page_token", description: "Pagination token from a previous list response" },
            ],
            deepLinkTemplate: "/ng/account/{accountId}/settings/organizations/{org}",
            operations: {
                list: {
                    method: "GET",
                    // NG: GET /ng/api/organizations?pageIndex=&pageSize=&searchTerm=&sortOrders=&pageToken=&identifiers=
                    path: "/ng/api/organizations",
                    operationPolicy: { risk: "read", retryPolicy: "safe" },
                    queryParams: {
                        search_term: "searchTerm",
                        page: "pageIndex",
                        size: "pageSize",
                        sort_orders: "sortOrders",
                        page_token: "pageToken",
                        identifiers: "identifiers",
                    },
                    responseExtractor: pageExtract,
                    description: "List organizations in the account",
                },
                get: {
                    method: "GET",
                    path: "/ng/api/organizations/{org}",
                    operationPolicy: { risk: "read", retryPolicy: "safe" },
                    pathParams: { org_id: "org" },
                    responseExtractor: unwrapOrgResponse,
                    description: "Get organization details",
                },
                create: {
                    method: "POST",
                    path: "/ng/api/organizations",
                    operationPolicy: { risk: "low_write", retryPolicy: "do_not_retry" },
                    bodyBuilder: buildOrgBody,
                    responseExtractor: unwrapOrgResponse,
                    description: "Create a new organization",
                    bodySchema: orgCreateSchema,
                    bodyWrapperKey: "organization",
                },
                update: {
                    method: "PUT",
                    path: "/ng/api/organizations/{org}",
                    operationPolicy: { risk: "low_write", retryPolicy: "safe" },
                    pathParams: { org_id: "org" },
                    bodyBuilder: buildOrgUpdateBody,
                    responseExtractor: unwrapOrgResponse,
                    description: "Update an existing organization",
                    bodySchema: orgUpdateSchema,
                    bodyWrapperKey: "organization",
                },
                delete: {
                    method: "DELETE",
                    path: "/ng/api/organizations/{org}",
                    operationPolicy: { risk: "destructive", retryPolicy: "do_not_retry" },
                    pathParams: { org_id: "org" },
                    responseExtractor: unwrapOrgResponse,
                    description: "Delete an organization",
                },
            },
        },
        // ----- Project -----
        {
            resourceType: "project",
            displayName: "Project",
            description: "Harness project within an organization. Scopes pipelines, services, environments, etc. Supports full CRUD via v1 API.",
            toolset: "platform",
            scope: "account",
            identifierFields: ["project_id"],
            listFilterFields: [
                { name: "identifiers", description: "Comma-separated project identifiers to filter" },
                { name: "search_term", description: "Search term (maps to searchTerm)" },
                { name: "has_module", description: "Filter by module presence (hasModule)" },
                { name: "module_type", description: "Module type (e.g. CD, CI)" },
                { name: "only_favorites", description: "Only favorited projects", type: "boolean" },
                { name: "sort_orders", description: "Sort descriptor, e.g. fieldName=name&orderType=ASC (maps to sortOrders)" },
                { name: "page_token", description: "Pagination token from a previous response" },
            ],
            deepLinkTemplate: "/ng/account/{accountId}/all/orgs/{org}/projects/{project}",
            operations: {
                list: {
                    method: "GET",
                    // NG: GET /ng/api/projects?accountIdentifier=&orgIdentifier=&… (accountIdentifier injected by client)
                    path: "/ng/api/projects",
                    operationPolicy: { risk: "read", retryPolicy: "safe" },
                    queryParams: {
                        org_id: "orgIdentifier",
                        has_module: "hasModule",
                        identifiers: "identifiers",
                        module_type: "moduleType",
                        search_term: "searchTerm",
                        only_favorites: "onlyFavorites",
                        page: "pageIndex",
                        size: "pageSize",
                        sort_orders: "sortOrders",
                        page_token: "pageToken",
                    },
                    responseExtractor: projectListExtract,
                    description: "List projects (NG /ng/api/projects)",
                },
                get: {
                    method: "GET",
                    // NG: GET /ng/api/projects/{projectIdentifier}?orgIdentifier=&accountIdentifier= (client injects account)
                    path: "/ng/api/projects/{project}",
                    operationPolicy: { risk: "read", retryPolicy: "safe" },
                    pathParams: { project_id: "project" },
                    queryParams: { org_id: "orgIdentifier" },
                    injectOrgQueryFallback: true,
                    responseExtractor: unwrapProjectResponse,
                    description: "Get project details",
                },
                create: {
                    method: "POST",
                    // NG: POST /ng/api/projects?orgIdentifier= — body { project: { orgIdentifier, identifier, name, ... } }
                    path: "/ng/api/projects",
                    operationPolicy: { risk: "low_write", retryPolicy: "do_not_retry" },
                    queryParams: { org_id: "orgIdentifier" },
                    injectOrgQueryFallback: true,
                    bodyBuilder: buildProjectBody,
                    responseExtractor: unwrapProjectResponse,
                    description: "Create a new project in an organization",
                    bodySchema: projectCreateSchema,
                    bodyWrapperKey: "project",
                },
                update: {
                    method: "PUT",
                    path: "/ng/api/projects/{project}",
                    operationPolicy: { risk: "low_write", retryPolicy: "safe" },
                    pathParams: { project_id: "project" },
                    queryParams: { org_id: "orgIdentifier" },
                    injectOrgQueryFallback: true,
                    bodyBuilder: buildProjectUpdateBody,
                    responseExtractor: unwrapProjectResponse,
                    description: "Update an existing project",
                    bodySchema: projectUpdateSchema,
                    bodyWrapperKey: "project",
                },
                delete: {
                    method: "DELETE",
                    path: "/ng/api/projects/{project}",
                    operationPolicy: { risk: "destructive", retryPolicy: "do_not_retry" },
                    pathParams: { project_id: "project" },
                    queryParams: { org_id: "orgIdentifier" },
                    injectOrgQueryFallback: true,
                    responseExtractor: unwrapProjectResponse,
                    description: "Delete a project",
                },
            },
        },
    ],
};
//# sourceMappingURL=platform.js.map