/**
 * Copyright IBM Corp. 2016, 2025
 * SPDX-License-Identifier: BUSL-1.1
 */

import AdapterError from '@ember-data/adapter/error';
import { set } from '@ember/object';
import ApplicationAdapter from './application';
import { sanitizePath, sanitizeStart } from 'core/utils/sanitize-path';

export default class CapabilitiesAdapter extends ApplicationAdapter {
  pathForType() {
    return 'capabilities-self';
  }

  /* 
  users don't always have access to the capabilities-self endpoint in the current namespace,
  this can happen when logging in to a namespace and then navigating to a child namespace.
  adding "relativeNamespace" to the path and/or "this.namespaceService.userRootNamespace"
  to the request header ensures we are querying capabilities-self in the user's root namespace,
  which is where they are most likely to have their policy/permissions.
  */
  _formatPath(path) {
    const { relativeNamespace } = this.namespaceService;
    if (!relativeNamespace) {
      return path;
    }
    // ensure original path doesn't have leading slash
    return `${relativeNamespace}/${sanitizeStart(path)}`;
  }

  async findRecord(store, type, id) {
    const paths = [this._formatPath(id)];
    return this.ajax(this.buildURL(type), 'POST', {
      data: { paths },
      namespace: sanitizePath(this.namespaceService.userRootNamespace),
    }).catch((e) => {
      if (e instanceof AdapterError) {
        set(e, 'policyPath', 'sys/capabilities-self');
      }
      throw e;
    });
  }

  queryRecord(store, type, query) {
    const { id } = query;
    if (!id) {
      return;
    }
    return this.findRecord(store, type, id).then((resp) => {
      resp.path = id;
      return resp;
    });
  }

  query(store, type, query) {
    const pathMap = query?.paths.reduce((mapping, path) => {
      const withNs = this._formatPath(path);
      if (withNs) {
        mapping[withNs] = path;
      }
      return mapping;
    }, {});

    return this.ajax(this.buildURL(type), 'POST', {
      data: { paths: Object.keys(pathMap) },
      namespace: sanitizePath(this.namespaceService.userRootNamespace),
    })
      .then((queryResult) => {
        if (queryResult) {
          // send the pathMap with the response so the serializer can normalize the paths to be relative to the namespace
          queryResult.pathMap = pathMap;
        }
        return queryResult;
      })
      .catch((e) => {
        if (e instanceof AdapterError) {
          set(e, 'policyPath', 'sys/capabilities-self');
        }
        throw e;
      });
  }
}
