import 'package:oto/oto/commands/command.dart';
import 'package:oto/oto/data/command_data.dart';
import 'package:xml/xml.dart' as xml;

class JenkinsParameterModify extends Command {
  Function? get error => null;

  @override
  Future execute(DataCommand command) async {
    var data = DataJenkinsParameterModify.fromJson(getParam(command));

    var startId = '<hudson.model.ParametersDefinitionProperty>';
    var start = data.content?.indexOf(startId);
    var end =
        data.content?.indexOf('</hudson.model.ParametersDefinitionProperty>');
    var startParam = start! + startId.length;
    var endParam = end!;
    var paramContent = data.content?.substring(start + startId.length, end);
    startId = '<name>${data.name}</name>';
    start = paramContent
        ?.substring(0, paramContent.indexOf(startId))
        .lastIndexOf('<');
    var findContent = paramContent?.substring(start!);
    end = findContent?.indexOf('>');
    var element = findContent?.substring(1, end! + 1);
    startId = '</$element';
    end = findContent?.indexOf(startId);
    var property = findContent?.substring(0, end! + startId.length);

    final def = xml.XmlDocument.parse(property!).rootElement;

    var paramName = def.getElement('name');
    if (paramName?.innerText == data.name) {
      switch (def.localName) {
        case 'hudson.model.ChoiceParameterDefinition':
          if (data.value is List) {
            var choices = def.getElement('choices');
            choices?.children.clear();
            var a = xml.XmlElement(xml.XmlName('a'),
                [xml.XmlAttribute(xml.XmlName('class'), 'string-array')]);
            for (var item in data.value) {
              a.children.add(xml.XmlElement(
                  xml.XmlName('string'), [], [xml.XmlText(item)]));
            }
            choices?.children.add(a);
          }
          break;
        default:
          var defaultValue = def.getElement('defaultValue');
          defaultValue?.innerText = data.value;
      }
      property = def.toXmlString();
    }

    paramContent = paramContent?.replaceRange(
        start!, start + end! + startId.length, property);

    var content =
        data.content?.replaceRange(startParam, endParam, paramContent!);

    setProperty(data.setContent!, content, showPrint: data.showPrint);

    return await complete(0, command);
  }
}

void registerJenkinsCommands() {
  Command.register(
    CommandType.JenkinsParameterModify,
    () => JenkinsParameterModify(),
    spec: const CommandSpec(
      type: CommandType.JenkinsParameterModify,
      category: 'jenkins',
      dataModel: 'DataJenkinsParameterModify',
      samplePath: 'assets/yaml/sample/20_jenkins.yaml',
    ),
  );
}
