Source: github/billing.js

/**
 * @fileoverview Billing operations for GitHub
 * @license Apache-2.0
 * @version 3.0.0
 * @author Michael Hay <michael.hay@mediumroast.io>
 * @copyright 2025 Mediumroast, Inc. All rights reserved.
 */

import ResponseFactory from './response.js';

/**
 * Manages GitHub billing operations
 */
class BillingManager {
  /**
   * @constructor
   * @param {Object} octokit - Octokit instance
   * @param {String} orgName - GitHub organization name
   */
  constructor(octokit, orgName) {
    this.octokit = octokit;
    this.orgName = orgName;
  }

  /**
   * Gets GitHub Actions billing information for the organization
   * @returns {Promise<Array>} ResponseFactory result
   */
  async getActionsBillings() {
    try {
      const response = await this.octokit.rest.billing.getGithubActionsBillingOrg({
        org: this.orgName,
      });
      
      return ResponseFactory.success(
        `Successfully retrieved Actions billing information for organization ${this.orgName}`,
        response.data
      );
    } catch (err) {
      return ResponseFactory.error(
        `Failed to retrieve Actions billing information: ${err.message}`,
        err,
        err.status || 500
      );
    }
  }

  /**
   * Gets GitHub Packages storage billing information for the organization
   * @returns {Promise<Array>} ResponseFactory result
   */
  async getStorageBillings() {
    try {
      const response = await this.octokit.rest.billing.getSharedStorageBillingOrg({
        org: this.orgName,
      });
      
      return ResponseFactory.success(
        `Successfully retrieved storage billing information for organization ${this.orgName}`,
        response.data
      );
    } catch (err) {
      return ResponseFactory.error(
        `Failed to retrieve storage billing information: ${err.message}`,
        err,
        err.status || 500
      );
    }
  }

  /**
   * Gets GitHub Packages billing information for the organization
   * @returns {Promise<Array>} ResponseFactory result
   */
  async getPackagesBillings() {
    try {
      const response = await this.octokit.rest.billing.getGithubPackagesBillingOrg({
        org: this.orgName,
      });
      
      return ResponseFactory.success(
        `Successfully retrieved Packages billing information for organization ${this.orgName}`,
        response.data
      );
    } catch (err) {
      return ResponseFactory.error(
        `Failed to retrieve Packages billing information: ${err.message}`,
        err,
        err.status || 500
      );
    }
  }

  /**
   * Gets all billing information for the organization
   * @returns {Promise<Array>} ResponseFactory result with combined billing data
   */
  async getAllBillings() {
    try {
      const [actionsResult, storageResult, packagesResult] = await Promise.all([
        this.getActionsBillings(),
        this.getStorageBillings(),
        this.getPackagesBillings()
      ]);
      
      if (!actionsResult[0] || !storageResult[0] || !packagesResult[0]) {
        const failedRequests = [];
        if (!actionsResult[0]) failedRequests.push('Actions');
        if (!storageResult[0]) failedRequests.push('Storage');
        if (!packagesResult[0]) failedRequests.push('Packages');
        
        return ResponseFactory.error(
          `Failed to retrieve some billing information: ${failedRequests.join(', ')}`,
          { actionsResult, storageResult, packagesResult },
          500
        );
      }
      
      const combinedData = {
        actions: actionsResult[2],
        storage: storageResult[2],
        packages: packagesResult[2]
      };
      
      return ResponseFactory.success(
        `Successfully retrieved all billing information for organization ${this.orgName}`,
        combinedData
      );
    } catch (err) {
      return ResponseFactory.error(
        `Failed to retrieve billing information: ${err.message}`,
        err
      );
    }
  }
}

export default BillingManager;