import { getComponentData } from '@backstage/core-plugin-api';
import { isValidElement, Children } from 'react';
import { EntityCardBlueprint, EntityContentBlueprint } from '@backstage/plugin-catalog-react/alpha';
import { normalizeRoutePath } from './normalizeRoutePath.esm.js';

const ENTITY_SWITCH_KEY = "core.backstage.entitySwitch";
const ENTITY_ROUTE_KEY = "plugin.catalog.entityLayoutRoute";
function allFilters(...ifs) {
  const filtered = ifs.filter(Boolean);
  if (!filtered.length) {
    return void 0;
  }
  if (filtered.length === 1) {
    return filtered[0];
  }
  return (entity, ctx) => filtered.every((ifFunc) => ifFunc(entity, ctx));
}
function anyFilters(...ifs) {
  const filtered = ifs.filter(Boolean);
  if (!filtered.length) {
    return void 0;
  }
  if (filtered.length === 1) {
    return filtered[0];
  }
  return (entity, ctx) => filtered.some((ifFunc) => ifFunc(entity, ctx));
}
function invertFilter(ifFunc) {
  if (!ifFunc) {
    return () => true;
  }
  return (entity, ctx) => !ifFunc(entity, ctx);
}
function collectEntityPageContents(entityPageElement, context) {
  let cardCounter = 1;
  let routeCounter = 1;
  function traverse(element, parentFilter) {
    if (!isValidElement(element)) {
      return;
    }
    const pageNode = maybeParseEntityPageNode(element);
    if (pageNode) {
      if (pageNode.type === "route") {
        const mergedIf = allFilters(parentFilter, pageNode.if);
        if (pageNode.path === "/") {
          context.discoverExtension(
            EntityCardBlueprint.makeWithOverrides({
              name: `discovered-${cardCounter++}`,
              factory(originalFactory, { apis }) {
                return originalFactory({
                  type: "content",
                  filter: mergedIf && ((entity) => mergedIf(entity, { apis })),
                  loader: () => Promise.resolve(pageNode.children)
                });
              }
            })
          );
        } else {
          const name = `discovered-${routeCounter++}`;
          context.discoverExtension(
            EntityContentBlueprint.makeWithOverrides({
              name,
              factory(originalFactory, { apis }) {
                return originalFactory({
                  defaultPath: normalizeRoutePath(pageNode.path),
                  defaultTitle: pageNode.title,
                  filter: mergedIf && ((entity) => mergedIf(entity, { apis })),
                  loader: () => Promise.resolve(pageNode.children)
                });
              }
            }),
            getComponentData(
              pageNode.children,
              "core.plugin"
            )
          );
        }
      }
      if (pageNode.type === "switch") {
        if (pageNode.renderMultipleMatches === "all") {
          for (const entityCase of pageNode.cases) {
            traverse(
              entityCase.children,
              allFilters(parentFilter, entityCase.if)
            );
          }
        } else {
          let previousIf = () => false;
          for (const entityCase of pageNode.cases) {
            const didNotMatchEarlier = invertFilter(previousIf);
            traverse(
              entityCase.children,
              allFilters(parentFilter, entityCase.if, didNotMatchEarlier)
            );
            previousIf = anyFilters(previousIf, entityCase.if);
          }
        }
      }
      return;
    }
    Children.forEach(
      element.props?.children,
      (child) => {
        traverse(child, parentFilter);
      }
    );
  }
  traverse(entityPageElement);
}
function wrapAsyncEntityFilter(asyncFilter) {
  if (!asyncFilter) {
    return asyncFilter;
  }
  let loggedError = false;
  return (entity, ctx) => {
    const result = asyncFilter(entity, ctx);
    if (result && typeof result === "object" && "then" in result) {
      if (!loggedError) {
        console.error(
          `collectEntityPageContents does not support async entity filters, skipping filter ${asyncFilter}`
        );
        loggedError = true;
      }
      return false;
    }
    return result;
  };
}
function maybeParseEntityPageNode(element) {
  if (getComponentData(element, ENTITY_ROUTE_KEY)) {
    const props = element.props;
    return {
      type: "route",
      path: props.path,
      title: props.title,
      if: props.if,
      children: props.children
    };
  }
  const parentProps = element.props;
  const children = Children.toArray(parentProps?.children);
  if (!children.length) {
    return void 0;
  }
  const cases = [];
  for (const child of children) {
    if (!getComponentData(child, ENTITY_SWITCH_KEY)) {
      return void 0;
    }
    const props = child.props;
    cases.push({
      if: wrapAsyncEntityFilter(props.if),
      children: props.children
    });
  }
  return {
    type: "switch",
    cases,
    renderMultipleMatches: parentProps?.renderMultipleMatches ?? "first"
  };
}

export { collectEntityPageContents };
//# sourceMappingURL=collectEntityPageContents.esm.js.map
