namespace :ldap do
  desc "Reset the LDAP directory and set up base entries and default org"
  task setup: [:environment, :add_custom_attributes] do |t, args|
    ldap = LdapService.new

    ldap.delete_entry "cn=admin_role,ou=kosmos.org,cn=users,dc=kosmos,dc=org", true

    # Delete all existing entries and re-add base entries
    ldap.reset_directory!

    ldap.add_organization "kosmos.org", "Kosmos", true

    # add admin role
    ldap.add_entry "cn=admin_role,ou=kosmos.org,cn=users,dc=kosmos,dc=org", {
      objectClass: %w{top LDAPsubentry nsRoleDefinition nsComplexRoleDefinition nsFilteredRoleDefinition},
      cn: "admin_role",
      nsRoleFilter: "(&(objectclass=person)(admin=true))",
      description: "filtered role for admins"
    }, true
  end

  desc "Add custom attributes to schema"
  task add_custom_attributes: :environment do |t, args|
    %w[ admin service_enabled nostr_key ].each do |name|
      Rake::Task["ldap:modify_ldap_schema"].invoke(name, "add")
      Rake::Task['ldap:modify_ldap_schema'].reenable
    end
  end

  desc "Delete custom attributes from schema"
  task delete_custom_attributes: :environment do |t, args|
    %w[ admin service_enabled nostr_key ].each do |name|
      Rake::Task["ldap:modify_ldap_schema"].invoke(name, "delete")
      Rake::Task['ldap:modify_ldap_schema'].reenable
    end
  end

  desc "Modify LDAP schema"
  task :modify_ldap_schema, [:name, :operation] => [:environment] do |t, args|
    puts "Modify schema: #{args[:operation]} #{args[:name]}"

    filename = "#{Rails.root}/schemas/ldap/#{args[:name]}.ldif"
    ldif = YAML.safe_load(File.read(filename))
    dn = ldif["dn"]
    attribute = ldif["add"]
    value = ldif[attribute]
    operation = [ args[:operation].to_sym, attribute.to_sym, value ]

    ldap = LdapService.new
    res = ldap.modify dn, [ operation ]

    if res != 0
      puts "Result code: #{res}"
      exit 1
    end
  end

  desc "List user domains/organizations"
  task list_organizations: :environment do |t, args|
    ldap = LdapService.new
    orgs = ldap.fetch_organizations
    puts orgs.inspect
  end
end
