# frozen_string_literal: true

require "mysql2"
require File.expand_path(File.dirname(__FILE__) + "/base.rb")

class ImportScripts::Elgg < ImportScripts::Base
  BATCH_SIZE ||= 1000

  def initialize
    super

    @client =
      Mysql2::Client.new(host: "127.0.0.1", port: "3306", username: "", database: "", password: "")

    SiteSetting.max_username_length = 50
  end

  def execute
    import_users
    import_categories
    import_topics
    import_posts
  end

  def create_avatar(user, guid)
    puts "#{@path}"
    # Put your avatar at the root of discourse in this folder:
    path_prefix = "import/data/www/"
    # https://github.com/Elgg/Elgg/blob/2fc9c1910a9169bbe4010026c61d8e41a5b56239/engine/classes/ElggDiskFilestore.php#L24
    # 	const BUCKET_SIZE = 5000;
    bucket_size = 5000
    #https://github.com/Elgg/Elgg/blob/0e7eedceaa96151f0cea0625b34f78d3d96a3e14/engine/classes/Elgg/EntityDirLocator.php#L80
    # 	return (int) max(floor($guid / $bucket_size) * $bucket_size, 1);
    bucket_id = [guid / bucket_size * bucket_size, 1].max

    avatar_path = File.join(path_prefix, bucket_id.to_s, "/#{guid}/profile/#{guid}master.jpg")
    @uploader.create_avatar(user, avatar_path) if File.exist?(avatar_path)
  end

  def grant_admin(user, is_admin)
    if is_admin == "yes"
      puts "", "#{user.username} is granted admin!"
      user.grant_admin!
    end
  end

  def import_users
    puts "", "importing users..."

    last_user_id = -1
    total_users =
      mysql_query("select count(*) from elgg_users_entity where banned='no'").first["count"]

    batches(BATCH_SIZE) do |offset|
      users = mysql_query(<<-SQL).to_a
        select eue.guid, eue.username, eue.name, eue.email, eue.admin,
        max(case when ems1.string='cae_structure' then ems2.string  end)cae_structure,
        max(case when ems1.string='location' then ems2.string  end)location,
        max(case when ems1.string='validated' then ems2.string  end)validated,
        max(case when ems1.string='briefdescription' then ems2.string  end)briefdescription,
        max(case when ems1.string='website' then ems2.string  end)website
        from elgg_users_entity eue
        join elgg_metadata em on em.entity_guid = eue.guid
        join elgg_metastrings ems1 on ems1.id = em.name_id
        join elgg_metastrings ems2 on ems2.id = em.value_id
        where
        eue.banned='no'
        and eue.guid > #{last_user_id}
        group by eue.guid
        LIMIT #{BATCH_SIZE}
      SQL

      break if users.empty?

      last_user_id = users[-1]["guid"]
      user_ids = users.map { |u| u["guid"].to_i }

      next if all_records_exist?(:users, user_ids)

      user_ids_sql = user_ids.join(",")

      create_users(users, total: total_users, offset: offset) do |u|
        if u["validated"] = 1
          {
            id: u["guid"].to_i,
            username: u["username"],
            location: u["location"],
            email: u["email"].downcase,
            name: u["name"],
            website: u["website"],
            bio_raw: u["briefdescription"].to_s + " " + u["cae_structure"].to_s,
            post_create_action:
              proc do |user|
                create_avatar(user, u["guid"])
                #add_user_to_group(user, u["cae_structure"])
                grant_admin(user, u["admin"])
              end,
          }
        end
      end
    end
  end

  def import_categories
    puts "", "importing categories..."

    categories = mysql_query("select guid, name, description from elgg_groups_entity")

    create_categories(categories) do |c|
      {
        id: c["guid"],
        name: CGI.unescapeHTML(c["name"]),
        description: CGI.unescapeHTML(c["description"]),
      }
    end
  end

  def import_topics
    puts "", "creating topics"

    total_count =
      mysql_query("select count(*) count from elgg_entities where subtype = 32;").first["count"]

    batches(BATCH_SIZE) do |offset|
      results =
        mysql_query(
          "
        SELECT
        ee.guid id,
        owner_guid user_id,
        container_guid category_id,
        time_created created_at,
        title,
        description raw
        FROM elgg_entities ee
        JOIN elgg_objects_entity eoe on ee.guid = eoe.guid
        WHERE
        subtype = 32
        ORDER BY ee.guid
        LIMIT #{BATCH_SIZE}
        OFFSET #{offset};
      ",
        )

      break if results.size < 1

      next if all_records_exist? :posts, results.map { |m| m["id"].to_i }

      create_posts(results, total: total_count, offset: offset) do |m|
        {
          id: m["id"],
          user_id: user_id_from_imported_user_id(m["user_id"]) || -1,
          raw: CGI.unescapeHTML(m["raw"]),
          created_at: Time.zone.at(m["created_at"]),
          category: category_id_from_imported_category_id(m["category_id"]),
          title: CGI.unescapeHTML(m["title"]),
          post_create_action:
            proc do |post|
              tag_names =
                mysql_query(
                  "
              select ms.string
              from elgg_metadata md
              join elgg_metastrings ms on md.value_id = ms.id
              where name_id = 43
              and entity_guid = #{m["id"]};
            ",
                ).map { |tag| tag["string"] }
              DiscourseTagging.tag_topic_by_names(post.topic, staff_guardian, tag_names)
            end,
        }
      end
    end
  end

  def staff_guardian
    @_staff_guardian ||= Guardian.new(Discourse.system_user)
  end

  def import_posts
    puts "", "creating posts"

    total_count =
      mysql_query("SELECT count(*) count FROM elgg_entities WHERE subtype = 42").first["count"]

    batches(BATCH_SIZE) do |offset|
      results =
        mysql_query(
          "
        SELECT
        ee.guid id,
        container_guid topic_id,
        owner_guid user_id,
        description raw,
        time_created created_at
        FROM elgg_entities ee
        JOIN elgg_objects_entity eoe ON ee.guid = eoe.guid
        WHERE subtype = 42
        ORDER BY ee.guid
        LIMIT #{BATCH_SIZE}
        OFFSET #{offset};
      ",
        )

      break if results.size < 1

      next if all_records_exist? :posts, results.map { |m| m["id"].to_i }

      create_posts(results, total: total_count, offset: offset) do |m|
        {
          id: m["id"],
          user_id: user_id_from_imported_user_id(m["user_id"]) || -1,
          topic_id: topic_lookup_from_imported_post_id(m["topic_id"])[:topic_id],
          raw: CGI.unescapeHTML(m["raw"]),
          created_at: Time.zone.at(m["created_at"]),
        }
      end
    end
  end

  def mysql_query(sql)
    @client.query(sql, cache_rows: false)
  end
end

ImportScripts::Elgg.new.perform