/*
 * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import groupBy from "object.groupby";
import invariant from "tiny-invariant";
import { ObjectDefRef } from "../../../object/convertWireToOsdkObjects/InternalSymbols.js";
import { ListQuery, RDP_IDX } from "./ListQuery.js";
export class InterfaceListQuery extends ListQuery {
  createObjectSet(store) {
    const rdpConfig = this.cacheKey.otherKeys[RDP_IDX];
    const objectTypeDef = {
      type: "interface",
      apiName: this.apiName
    };
    if (rdpConfig != null) {
      return store.client(objectTypeDef).withProperties(rdpConfig).where(this.canonicalWhere);
    }
    return store.client(objectTypeDef).where(this.canonicalWhere);
  }
  async revalidateObjectType(apiName) {
    const objectMetadata = await this.store.client.fetchMetadata({
      type: "object",
      apiName
    });
    if (this.apiName in objectMetadata.interfaceMap) {
      await this.revalidate(/* force */true);
    }
  }
  async postProcessFetchedData(data) {
    return reloadDataAsFullObjects(this.store.client, data);
  }
  createPayload(params) {
    const resolvedList = params.resolvedData.map(obj => obj.$as(this.apiName));
    return {
      resolvedList,
      isOptimistic: params.isOptimistic,
      fetchMore: this.fetchMore,
      hasMore: this.nextPageToken != null,
      status: params.status,
      lastUpdated: params.lastUpdated
    };
  }
  extractRelevantObjects(changes) {
    const matchesApiName = ([, object]) => {
      return this.apiName in object[ObjectDefRef].interfaceMap;
    };
    const added = Array.from(changes.addedObjects).filter(matchesApiName).map(([, object]) => object.$as(this.apiName));
    const modified = Array.from(changes.modifiedObjects).filter(matchesApiName).map(([, object]) => object.$as(this.apiName));
    return {
      added: {
        all: added,
        strictMatches: new Set(),
        sortaMatches: new Set()
      },
      modified: {
        all: modified,
        strictMatches: new Set(),
        sortaMatches: new Set()
      }
    };
  }
}

// Hopefully this can go away when we can just request the full object properties on first load
async function reloadDataAsFullObjects(client, data) {
  if (data.length === 0) {
    return data;
  }
  const groups = groupBy(data, x => x.$objectType);
  const objectTypeToPrimaryKeyToObject = Object.fromEntries(await Promise.all(Object.entries(groups).map(async ([apiName, objects]) => {
    // Interface query results don't have ObjectDefRef, so we fetch metadata to get primaryKeyApiName
    const objectDef = await client.fetchMetadata({
      type: "object",
      apiName
    });
    const where = {
      [objectDef.primaryKeyApiName]: {
        $in: objects.map(x => x.$primaryKey)
      }
    };
    const result = await client(objectDef).where(where).fetchPage({
      $includeRid: true
    });
    return [apiName, Object.fromEntries(result.data.map(x => [x.$primaryKey, x]))];
  })));
  return data.map(obj => {
    const fullObject = objectTypeToPrimaryKeyToObject[obj.$objectType][obj.$primaryKey];
    !fullObject ? process.env.NODE_ENV !== "production" ? invariant(false, `Could not find object ${obj.$objectType} ${obj.$primaryKey}`) : invariant(false) : void 0;
    return fullObject;
  });
}
//# sourceMappingURL=InterfaceListQuery.js.map