---
to: "{{ project_name }}/src/cmds/{{ noun }}/{{ verb }}.rs"
sparql:
  verb_info: |
    PREFIX cnv: <http://ggen.dev/schema/clap-noun-verb#>
    SELECT ?verbDescription ?alias
    WHERE {
      ?noun cnv:nounName "{{ noun }}" ;
            cnv:hasVerb ?verb .
      ?verb cnv:verbName "{{ verb }}" ;
            cnv:verbDescription ?verbDescription .
      OPTIONAL { ?verb cnv:verbAlias ?alias }
    }
  arguments: |
    PREFIX cnv: <http://ggen.dev/schema/clap-noun-verb#>
    SELECT ?argName ?argLong ?argShort ?argHelp ?argRequired 
           ?argDefault ?argPosition ?typeName
    WHERE {
      ?noun cnv:nounName "{{ noun }}" ;
            cnv:hasVerb ?verb .
      ?verb cnv:verbName "{{ verb }}" ;
            cnv:hasArgument ?arg .
      ?arg cnv:argName ?argName ;
           cnv:argHelp ?argHelp .
      OPTIONAL { ?arg cnv:argLong ?argLong }
      OPTIONAL { ?arg cnv:argShort ?argShort }
      OPTIONAL { ?arg cnv:argRequired ?argRequired }
      OPTIONAL { ?arg cnv:argDefault ?argDefault }
      OPTIONAL { ?arg cnv:argPosition ?argPosition }
      OPTIONAL {
        ?arg cnv:hasType ?type .
        ?type cnv:typeName ?typeName
      }
    }
    ORDER BY ?argPosition ?argName
  noun_info: |
    PREFIX cnv: <http://ggen.dev/schema/clap-noun-verb#>
    SELECT ?nounDescription
    WHERE {
      ?noun cnv:nounName "{{ noun }}" ;
            cnv:nounDescription ?nounDescription .
    }
---
//! {% if sparql_results.verb_info | length > 0 %}{{ sparql_results.verb_info[0].verbDescription }}{% else %}{{ verb | capitalize }} {{ noun }} command{% endif %}

use clap_noun_verb_macros::verb;
use clap_noun_verb::Result;
use serde::Serialize;

#[derive(Debug, Serialize)]
pub struct {{ verb | capitalize }}Result {
    id: String,
    message: String,
    {% for arg in sparql_results.arguments %}
    {% if arg.typeName == "String" or arg.typeName == "Option<String>" %}{{ arg.argName }}: {{ arg.typeName }},
    {% endif %}
    {% endfor %}
}

/// {% if sparql_results.verb_info | length > 0 %}{{ sparql_results.verb_info[0].verbDescription }}{% else %}{{ verb | capitalize }} a {{ noun }}{% endif %}
#[verb] // Verb "{{ verb }}" auto-inferred, noun "{{ noun }}" auto-inferred from directory
pub fn {{ verb }}_{{ noun }}(
    {% for arg in sparql_results.arguments %}
    /// {{ arg.argHelp }}
    {% if arg.argPosition is defined and arg.argPosition != "" %}
    #[arg(index = {{ arg.argPosition }})]
    {% elif arg.argLong is defined and arg.argLong != "" %}
    #[arg(long = "{{ arg.argLong }}"{% if arg.argShort is defined and arg.argShort != "" %}, short = '{{ arg.argShort }}'{% endif %}{% if arg.argDefault is defined and arg.argDefault != "" %}, default_value = "{{ arg.argDefault }}"{% endif %})]
    {% else %}
    #[arg]
    {% endif %}
    {{ arg.argName }}: {% if arg.typeName is defined and arg.typeName != "" %}{{ arg.typeName }}{% else %}String{% endif %},
    {% endfor %}
) -> Result<{{ verb | capitalize }}Result> {
    // TODO: Implement {{ verb }} logic here
    let result = {{ verb | capitalize }}Result {
        id: format!("{{ noun }}-{}", {% for arg in sparql_results.arguments %}{% if arg.argPosition is defined and arg.argPosition == "0" %}{{ arg.argName }}{% endif %}{% endfor %}{% if sparql_results.arguments | length == 0 %}"default"{% endif %}),
        message: format!("{{ noun | capitalize }} {{ verb }}d successfully!"),
        {% for arg in sparql_results.arguments %}
        {% if arg.typeName == "String" or arg.typeName == "Option<String>" %}{{ arg.argName }}: {{ arg.argName }},
        {% endif %}
        {% endfor %}
    };

    Ok(result)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_{{ verb }}_basic() {
        let result = {{ verb }}_{{ noun }}(
            {% for arg in sparql_results.arguments %}
            {% if arg.argPosition is defined and arg.argPosition == "0" %}"test-{{ noun }}".to_string(){% elif arg.typeName == "bool" %}false{% elif arg.typeName == "Option<String>" %}None{% elif arg.typeName == "String" %}"test".to_string(){% endif %}{% if not loop.last %},
            {% endif %}
            {% endfor %}
        );
        assert!(result.is_ok());
    }
}
