/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

// Generates the `/services` documentation section from `data/services.json`
// (produced by `just generate docs`). Every service gets a page with language
// tabs, and every supported (service, binding) pair gets a deep-linkable page
// such as `/services/s3/python`. These routes are registered programmatically
// so they stay out of the autogenerated docs sidebar while remaining real,
// statically rendered URLs.

const path = require("path");
const fs = require("fs");

// Join path segments under the site's baseUrl, collapsing duplicate slashes.
// Avoids depending on @docusaurus/utils, which pnpm does not hoist to a place
// resolvable from this plugin file.
function joinUrl(parts) {
  const joined = parts.join("/").replace(/\/{2,}/g, "/");
  return joined.startsWith("/") ? joined : `/${joined}`;
}

module.exports = function servicesDocsPlugin(context) {
  const { baseUrl } = context;

  return {
    name: "opendal-services-docs",

    async loadContent() {
      const dataPath = path.resolve(__dirname, "../data/services.json");
      const raw = fs.readFileSync(dataPath, "utf8");
      return JSON.parse(raw);
    },

    async contentLoaded({ content, actions }) {
      const { createData, addRoute } = actions;
      const { bindings, services } = content;

      const indexComponent =
        "@site/src/components/services/ServicesIndex.jsx";
      const pageComponent = "@site/src/components/services/ServicePage.jsx";

      // The index only needs a slim summary per service, not full snippets.
      const summary = services.map((s) => ({
        name: s.name,
        scheme: s.scheme,
        bindings: s.examples.map((e) => e.binding),
        configCount: s.configs.length,
      }));
      const indexData = await createData(
        "services-index.json",
        JSON.stringify({ bindings, services: summary })
      );
      addRoute({
        path: joinUrl([baseUrl, "services"]),
        component: indexComponent,
        modules: { data: indexData },
        exact: true,
      });

      for (const service of services) {
        const data = await createData(
          `service-${service.scheme}.json`,
          JSON.stringify({ bindings, service })
        );
        addRoute({
          path: joinUrl([baseUrl, "services", service.scheme]),
          component: pageComponent,
          modules: { data },
          exact: true,
        });
        for (const example of service.examples) {
          addRoute({
            path: joinUrl([
              baseUrl,
              "services",
              service.scheme,
              example.binding,
            ]),
            component: pageComponent,
            modules: { data },
            exact: true,
          });
        }
      }
    },
  };
};
