--- Saved Variables Updater
--
local Updater = {}

--- Example Use
-----------------------------

--local updates = {
--    {
--        version = "v-0.9.25-alpha",
--        details = "Added Updates",
--        db = {
--            apply = function()
--            end,
--            revert = function()
--            end,
--        },
--        profile = {
--            apply = function()
--            end,
--            revert = function()
--            end,
--        },
--    },
--};

local AddOnName, nsVars = ...
local ss = nsVars.SS

local udbVersion = 6

local updates = {
  {-- 1
    version = "v-0.9.25-alpha",
    details = "Pet and additional resource tracking are now account wide",
    global = {
      apply = function()
        if ss.db.track then
          ss.global.track.additionalResource = ss.global.track.additionalResourc or ss.db.track.additionalResource
          ss.global.track.pet = ss.global.track.pet or ss.db.track.pet
        end
      end,
      revert = function()
        ss.global.track = nil
      end,
    },
  },
  {-- 2
    version = "v-0.9.25-alpha",
    details = "Pet and additional resource tracking are now account wide",
    db = {
      apply = function()
        ss.db.track = nil
      end,
      revert = function()
        if ss.global.track then
          ss.db.track = ss.db.track or {}
          ss.db.track.additionalResource = ss.global.track.additionalResource
          ss.db.track.pet = ss.global.track.pet
        end
      end,
    },
  },
  {--3
    version = "v-0.9.39-alpha",
    details = "Moved Swirl Configuration Into Modes.",
    global = {
      apply = function()
        for dbn, db in pairs(ss.global) do
          local profileStart = { string.split("_", dbn) };

          if profileStart[1] == "SSProfile" then
            for _, v in pairs(db) do
              if type(v) == "table" and v.swirl then
                local swirl = v.swirl
                swirl.groupId = "swirl"
                swirl.id = v.swirl.id or "galaxy"
                swirl.speed = v.swirl.speed or 5
                for _, vv in pairs(v.modes) do
                  --Specs
                  for _, vvv in pairs(vv) do
                    --modes
                    vvv.swirl = swirl
                  end
                end
                v.swirl = nil
              end
            end
          end
        end
      end,
      revert = function()
        for dbn, db in pairs(ss.global) do
          local profileStart = { string.split("_", dbn) };

          if profileStart[1] == "SSProfile" then
            for _, v in pairs(db) do
              if type(v) == "table" and v.modes and not v.swirl then
                for _, vv in pairs(v.modes) do
                  --Specs
                  for _, vvv in pairs(vv) do
                    --modes
                    v.swirl = v.swirl or vvv.swirl
                    vvv.swirl = nil
                  end
                end
              end
            end
          end
        end
      end,
    },
  },
  {
    --4
    version = "v-0.9.41-alpha",
    details = "Added notification for texture packs.",
    global = {
      apply = function()
        ss.PendingTask.add("notification", function()
          ss.Notification:Notify("New Textures Available!", "Install \"Seamore Spheres Technology Textures\" to try them out. (No configuration required)")
        end)
      end,
      revert = function()
      end,
    },
  },
  {
    --5
    version = "v-0.9.69-alpha",
    details = "Moved sphere scaling to resources.",
    db = {
      apply = function()
        if ss.global.general.scale then
          -- Keep saved value.
          ss.db.health.general.globalScale = ss.global.general.scale
          ss.db.mainResource.general.globalScale = ss.global.general.scale
          ss.db.pet.general.globalScale = ss.global.general.scale
          ss.db.additionalResource.general.globalScale = ss.global.general.scale
        end
      end,
      revert = function()
      end,
    },
  },
  {
    --6
    version = "v-0.9.85-alpha",
    details = "Copying health/mainResource values into vehicle resources.",
    db = {
      apply = function()
        ss.db.vehicle.general.globalScale = ss.db.health.general.globalScale
        ss.db.vehicle.general.anchor = ss.db.health.general.anchor
        ss.db.vehicle.general.posX = ss.db.health.general.posX
        ss.db.vehicle.general.posY = ss.db.health.general.posY
        ss.db.vehicleResource.general.globalScale = ss.db.mainResource.general.globalScale
        ss.db.vehicleResource.general.anchor = ss.db.mainResource.general.anchor
        ss.db.vehicleResource.general.posX = ss.db.mainResource.general.posX
        ss.db.vehicleResource.general.posY = ss.db.mainResource.general.posY
      end,
      revert = function()
      end,
    },
  },
}

--- Updates a storage table to the target version.
-- @param db The table index.
-- @param latest The target version.
--
local function update(db, latest)
  -- defaults to 0 to ensure new characters include all updates.
  local currentDB = ss[db].latestUpdate or 0

  if currentDB < latest then
    -- perform updates
    for v = currentDB + 1, latest do
      if updates[v] and updates[v][db] then
        updates[v][db].apply()
        ss[db].latestUpdate = v
      end
    end
  elseif currentDB > latest then
    -- perform reverts
    for v = currentDB, latest + 1, -1 do
      if updates[v] and updates[v][db] then
        updates[v][db].revert()
        ss[db].latestUpdate = v - 1
      end
    end
  end

  if not ss[db].latestUpdate then
    -- Ensure this value gets initialized.
    ss[db].latestUpdate = latest
  end
end

function Updater.update()
  -- Update to target versions.
  update("db", udbVersion)
  update("global", udbVersion)
  update("profile", udbVersion)
  update("private", udbVersion)
end

ss.Utils.addModule("Updater", Updater)
