const fs = require('fs');
const pathLib = require('path');
const tar = require("tar");
const ignore = require("ignore");
const { promisify } = require('util');
const libClient = require('../client.js');
const { getAllFiles, showConsoleLink } = require('../utils.js');
const { Command } = require('commander');
const { sdkForProject, sdkForConsole } = require('../sdks')
const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
const { localConfig, globalConfig } = require("../config");
const { File } = require('undici');
const { ReadableStream } = require('stream/web');

/**
 * @param {fs.ReadStream} readStream
 * @returns {ReadableStream}
 */
function convertReadStreamToReadableStream(readStream) {
  return new ReadableStream({
    start(controller) {
      readStream.on("data", (chunk) => {
        controller.enqueue(chunk);
      });
      readStream.on("end", () => {
        controller.close();
      });
      readStream.on("error", (err) => {
        controller.error(err);
      });
    },
    cancel() {
      readStream.destroy();
    },
  });
}

const {{ service.name | caseLower }} = new Command("{{ service.name | caseLower }}").description(commandDescriptions['{{ service.name | caseLower }}'] ?? '').configureHelp({
    helpWidth: process.stdout.columns || 80
})

{% for method in service.methods %}
/**
 * @typedef {Object} {{ service.name | caseUcfirst }}{{ method.name | caseUcfirst }}RequestParams
{% for parameter in method.parameters.all %}
 * @property {{ "{" }}{{ parameter | typeName }}{{ "}" }} {{ parameter.name | caseCamel | escapeKeyword }} {{ parameter.description | replace({'`':'\''}) | replace({'\n':' '}) | replace({'\n \n':' '}) }}
{% endfor %}
 * @property {boolean} overrideForCli
 * @property {boolean} parseOutput
 * @property {libClient | undefined} sdk
{% if 'multipart/form-data' in method.consumes %}
 * @property {CallableFunction} onProgress
{% endif %}
{% if method.type == 'location' %}
 * @property {string} destination
{% endif %}
 */

/**
 * @param {{ "{" }}{{ service.name | caseUcfirst }}{{ method.name | caseUcfirst }}RequestParams{{ "}" }} params
 */
{%~ block decleration -%}
const {{ service.name | caseLower }}{{ method.name | caseUcfirst }} = async ({
        {%- for parameter in method.parameters.all -%}
            {{ parameter.name | caseCamel | escapeKeyword }},
        {%- endfor -%}

        {%- block baseParams -%}parseOutput = true, overrideForCli = false, sdk = undefined {%- endblock -%}

        {%- if 'multipart/form-data' in method.consumes -%},onProgress = () => {}{%- endif -%}

        {%- if method.type == 'location' -%}, destination{%- endif -%}
        {% if hasConsolePreview(method.name,service.name) %}, console{%- endif -%}
}) => {
{%~ endblock %}
    let client = !sdk ? await {% if service.name == "projects" %}sdkForConsole(){% else %}sdkForProject(){% endif %} :
    sdk;
    let apiPath = '{{ method.path }}'{% for parameter in method.parameters.path %}.replace('{{ '{' }}{{ parameter.name | caseCamel }}{{ '}' }}', {{ parameter.name | caseCamel | escapeKeyword }}){% endfor %};
{{ include ('cli/base/params.twig') }}
{% if 'multipart/form-data' in method.consumes %}
{{ include ('cli/base/requests/file.twig') }}{% else %}
{{ include('cli/base/requests/api.twig') }}
{% endif %}
}

{% endfor %}
{% for method in service.methods %}
{{service.name | caseLower }}
    .command(`{{ method.name | caseKebab }}`)
{% autoescape false %}
    .description(`{{ method.description | replace({'`':'\''}) | replace({'\n':' '}) | replace({'\n \n':' '}) }}`)
{% for parameter in method.parameters.all %}
    .{% if parameter.required and not parameter.nullable %}requiredOption{% else %}option{% endif %}(`--{{ parameter.name | escapeKeyword | caseKebab }} {% if parameter.array.type|length > 0 %}[{% else %}<{% endif %}{{ parameter.name | escapeKeyword | caseKebab }}{% if parameter.array.type|length > 0 %}...{% endif %}{% if parameter.array.type|length > 0 %}]{% else %}>{% endif %}`, `{{ parameter.description | replace({'`':'\''}) | replace({'\n':' '}) | replace({'\n \n':' '}) }}`{% if parameter | typeName == 'boolean' %}, parseBool{% elseif parameter | typeName == 'number' %}, parseInteger{% endif %})
{% endfor %}
{% if method.type == 'location' %}
    .requiredOption(`--destination <path>`, `output file path.`)
{% endif %}
{% if hasConsolePreview(method.name,service.name) %}
    .option(`--console`, `Get the resource console url`)
{% endif %}
{% endautoescape %}
    .action(actionRunner({{ service.name | caseLower }}{{ method.name | caseUcfirst }}))

{% endfor %}
module.exports = {
    {{ service.name | caseLower }},
{% for method in service.methods %}
    {{ service.name | caseLower }}{{ method.name | caseUcfirst }}{% if not loop.last %},{% endif %}

{% endfor %}
};
