<commit_before>defmodule Worker.Services.TilesCalculator do

  @imageroot "/imageroot/"
  @tile_size 256

#    size = 6000
#    project = "wes"
#    image_id = "6c5f936b-dba9-bf57-b681-5fc292e00e0b"

  def calc_tiles(project, image_id, image_size = {size_x, size_y}) do

    template = create_template(image_size, @tile_size)

    # todo: build all commands, then flatten, then execute them
    commands = Enum.map(template, fn {{rescale, entries}, z} ->
      rescale = floor(rescale)
      {cmd, args} = make_rescale_command(project, rescale, rescale)
      System.cmd(cmd, args)
      Enum.map(entries,
        fn entry ->
           {cmd_a, args_a, cmd_b, args_b} = make_crop_commands(
             project, @tile_size, "#{image_id}.#{rescale}.jpg", image_id, z, entry)
           System.cmd(cmd_a, args_a)
           System.cmd(cmd_b, args_b)
           nil
        end)
    end)
    nil
  end

  defp create_template(image_size = {size_x, size_y}, tile_size) do
    Stream.unfold({:continue, image_size}, fn {run, current_size = {current_size_x, current_size_y}} ->
      if run != :continue do
        nil
      else
        {
          {
            current_size,
            List.flatten(calc_template(current_size, tile_size))
          },
          {
            if current_size_x < tile_size do :halt else :continue end,
            {current_size_x / 2, current_size_y / 2}
          }
        }
      end
    end) |> Enum.to_list() |> Enum.reverse() |> Enum.with_index()
  end

  defp calc_template(current_size, tile_size) do
    fit_times = Integer.floor_div(floor(current_size), tile_size) + if Integer.mod(floor(current_size), tile_size) != 0 do 1 else 0 end
    Enum.reduce(
      0 .. fit_times-1,
      [],
      fn x_val, acc ->
        acc ++ [
          Enum.reduce(
            0 .. fit_times-1,
            [],
            fn y_val, acc ->
              acc ++ [
                %{
                  x_index: x_val,
                  y_index: y_val,
                  x_pos: x_val * tile_size,
                  y_pos: y_val * tile_size
                }
              ]
            end
          )
        ]
      end
    )
  end

  defp make_rescale_command(project, rescale_x, rescale_y) do<commit_msg>Rename vars<commit_after>defmodule Worker.Services.TilesCalculator do

  @imageroot "/imageroot/"
  @tile_size 256

#    size = 6000
#    project = "wes"
#    image_id = "6c5f936b-dba9-bf57-b681-5fc292e00e0b"

  def calc_tiles(project, image_id, image_size = {size_x, size_y}) do

    template = create_template(image_size, @tile_size)

    # todo: build all commands, then flatten, then execute them
    commands = Enum.map(template, fn {{rescale, entries}, z} ->
      rescale = floor(rescale)
      {cmd, args} = make_rescale_command(project, rescale, rescale)
      System.cmd(cmd, args)
      Enum.map(entries,
        fn entry ->
           {cmd_a, args_a, cmd_b, args_b} = make_crop_commands(
             project, @tile_size, "#{image_id}.#{rescale}.jpg", image_id, z, entry)
           System.cmd(cmd_a, args_a)
           System.cmd(cmd_b, args_b)
           nil
        end)
    end)
    nil
  end

  defp create_template(image_size = {size_x, size_y}, tile_size) do
    Stream.unfold({:continue, image_size}, fn {run, current_size = {current_size_x, current_size_y}} ->
      if run != :continue do
        nil
      else
        {
          {
            current_size,
            List.flatten(calc_template(current_size, tile_size))
          },
          {
            if current_size_x < tile_size do :halt else :continue end,
            {current_size_x / 2, current_size_y / 2}
          }
        }
      end
    end) |> Enum.to_list() |> Enum.reverse() |> Enum.with_index()
  end

  defp calc_template(current_size, tile_size) do
    fit_times = Integer.floor_div(floor(current_size), tile_size) + if Integer.mod(floor(current_size), tile_size) != 0 do 1 else 0 end
    Enum.reduce(
      0 .. fit_times-1,
      [],
      fn x_val, x_acc ->
        x_acc ++ [
          Enum.reduce(
            0 .. fit_times-1,
            [],
            fn y_val, y_acc ->
              y_acc ++ [
                %{
                  x_index: x_val,
                  y_index: y_val,
                  x_pos: x_val * tile_size,
                  y_pos: y_val * tile_size
                }
              ]
            end
          )
        ]
      end
    )
  end

  defp make_rescale_command(project, rescale_x, rescale_y) do
{'fraction_non_alphanumeric': 0.10837438423645321, 'fraction_numerical': 0.01522615315718764, 'mean_word_length': 1.8307984790874525, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1876121', 'n_tokens_mistral': 1565, 'n_tokens_neox': 1506, 'n_words': 316}