defmodule Imagineer.Image.PNG.PngSuite.Background.BackgroundTest do
  use ExUnit.Case, async: true

  @test_path "test/support/images/pngsuite/background/"
  @tmp_path "./tmp/"

  @actual_pixels [
    [
      {255, 0},
      {255, 8},
      {255, 16},
      {255, 24},
      {255, 32},
      {255, 41},
      {255, 49},
      {255, 57},
      {255, 65},
      {255, 74},
      {255, 82},
      {255, 90},
      {255, 98},
      {255, 106},
      {255, 115},
      {255, 123},
      {255, 131},
      {255, 139},
      {255, 148},
      {255, 156},
      {255, 164},
      {255, 172},
      {255, 180},
      {255, 189},
      {255, 197},
      {255, 205},
      {255, 213},
      {255, 222},
      {255, 230},
      {255, 238},
      {255, 246},
      {255, 255}
    ],
    [
      {246, 0},
      {246, 8},
      {246, 16},
      {246, 24},
      {246, 32},
      {246, 41},
      {246, 49},
      {246, 57},
      {246, 65},
      {246, 74},
      {246, 82},
      {246, 90},
      {246, 98},
      {246, 106},
      {246, 115},
      {246, 123},
      {246, 131},
      {246, 139},
      {246, 148},
      {246, 156},
      {246, 164},
      {246, 172},
      {246, 180},
      {246, 189},
      {246, 197},
      {246, 205},
      {246, 213},
      {246, 222},
      {246, 230},
      {246, 238},
      {246, 246},
      {246, 255}
    ],
    [
      {238, 0},
      {238, 8},
      {238, 16},
      {238, 24},
      {238, 32},
      {238, 41},
      {238, 49},
      {238, 57},
      {238, 65},
      {238, 74},
      {238, 82},
      {238, 90},
      {238, 98},
      {238, 106},
      {238, 115},
      {238, 123},
      {238, 131},
      {238, 139},
      {238, 148},
      {238, 156},
      {238, 164},
      {238, 172},
      {238, 180},
      {238, 189},
      {238, 197},
      {238, 205},
      {238, 213},
      {238, 222},
      {238, 230},
      {238, 238},
      {238, 246},
      {238, 255}
    ],
    [
      {230, 0},
      {230, 8},
      {230, 16},
      {230, 24},
      {230, 32},
      {230, 41},
      {230, 49},
      {230, 57},
      {230, 65},
      {230, 74},
      {230, 82},
      {230, 90},
      {230, 98},
      {230, 106},
      {230, 115},
      {230, 123},
      {230, 131},
      {230, 139},
      {230, 148},
      {230, 156},
      {230, 164},
      {230, 172},
      {230, 180},
      {230, 189},
      {230, 197},
      {230, 205},
      {230, 213},
      {230, 222},
      {230, 230},
      {230, 238},
      {230, 246},
      {230, 255}
    ],
    [
      {222, 0},
      {222, 8},
      {222, 16},
      {222, 24},
      {222, 32},
      {222, 41},
      {222, 49},
      {222, 57},
      {222, 65},
      {222, 74},
      {222, 82},
      {222, 90},
      {222, 98},
      {222, 106},
      {222, 115},
      {222, 123},
      {222, 131},
      {222, 139},
      {222, 148},
      {222, 156},
      {222, 164},
      {222, 172},
      {222, 180},
      {222, 189},
      {222, 197},
      {222, 205},
      {222, 213},
      {222, 222},
      {222, 230},
      {222, 238},
      {222, 246},
      {222, 255}
    ],
    [
      {213, 0},
      {213, 8},
      {213, 16},
      {213, 24},
      {213, 32},
      {213, 41},
      {213, 49},
      {213, 57},
      {213, 65},
      {213, 74},
      {213, 82},
      {213, 90},
      {213, 98},
      {213, 106},
      {213, 115},
      {213, 123},
      {213, 131},
      {213, 139},
      {213, 148},
      {213, 156},
      {213, 164},
      {213, 172},
      {213, 180},
      {213, 189},
      {213, 197},
      {213, 205},
      {213, 213},
      {213, 222},
      {213, 230},
      {213, 238},
      {213, 246},
      {213, 255}
    ],
    [
      {205, 0},
      {205, 8},
      {205, 16},
      {205, 24},
      {205, 32},
      {205, 41},
      {205, 49},
      {205, 57},
      {205, 65},
      {205, 74},
      {205, 82},
      {205, 90},
      {205, 98},
      {205, 106},
      {205, 115},
      {205, 123},
      {205, 131},
      {205, 139},
      {205, 148},
      {205, 156},
      {205, 164},
      {205, 172},
      {205, 180},
      {205, 189},
      {205, 197},
      {205, 205},
      {205, 213},
      {205, 222},
      {205, 230},
      {205, 238},
      {205, 246},
      {205, 255}
    ],
    [
      {197, 0},
      {197, 8},
      {197, 16},
      {197, 24},
      {197, 32},
      {197, 41},
      {197, 49},
      {197, 57},
      {197, 65},
      {197, 74},
      {197, 82},
      {197, 90},
      {197, 98},
      {197, 106},
      {197, 115},
      {197, 123},
      {197, 131},
      {197, 139},
      {197, 148},
      {197, 156},
      {197, 164},
      {197, 172},
      {197, 180},
      {197, 189},
      {197, 197},
      {197, 205},
      {197, 213},
      {197, 222},
      {197, 230},
      {197, 238},
      {197, 246},
      {197, 255}
    ],
    [
      {189, 0},
      {189, 8},
      {189, 16},
      {189, 24},
      {189, 32},
      {189, 41},
      {189, 49},
      {189, 57},
      {189, 65},
      {189, 74},
      {189, 82},
      {189, 90},
      {189, 98},
      {189, 106},
      {189, 115},
      {189, 123},
      {189, 131},
      {189, 139},
      {189, 148},
      {189, 156},
      {189, 164},
      {189, 172},
      {189, 180},
      {189, 189},
      {189, 197},
      {189, 205},
      {189, 213},
      {189, 222},
      {189, 230},
      {189, 238},
      {189, 246},
      {189, 255}
    ],
    [
      {180, 0},
      {180, 8},
      {180, 16},
      {180, 24},
      {180, 32},
      {180, 41},
      {180, 49},
      {180, 57},
      {180, 65},
      {180, 74},
      {180, 82},
      {180, 90},
      {180, 98},
      {180, 106},
      {180, 115},
      {180, 123},
      {180, 131},
      {180, 139},
      {180, 148},
      {180, 156},
      {180, 164},
      {180, 172},
      {180, 180},
      {180, 189},
      {180, 197},
      {180, 205},
      {180, 213},
      {180, 222},
      {180, 230},
      {180, 238},
      {180, 246},
      {180, 255}
    ],
    [
      {172, 0},
      {172, 8},
      {172, 16},
      {172, 24},
      {172, 32},
      {172, 41},
      {172, 49},
      {172, 57},
      {172, 65},
      {172, 74},
      {172, 82},
      {172, 90},
      {172, 98},
      {172, 106},
      {172, 115},
      {172, 123},
      {172, 131},
      {172, 139},
      {172, 148},
      {172, 156},
      {172, 164},
      {172, 172},
      {172, 180},
      {172, 189},
      {172, 197},
      {172, 205},
      {172, 213},
      {172, 222},
      {172, 230},
      {172, 238},
      {172, 246},
      {172, 255}
    ],
    [
      {164, 0},
      {164, 8},
      {164, 16},
      {164, 24},
      {164, 32},
      {164, 41},
      {164, 49},
      {164, 57},
      {164, 65},
      {164, 74},
      {164, 82},
      {164, 90},
      {164, 98},
      {164, 106},
      {164, 115},
      {164, 123},
      {164, 131},
      {164, 139},
      {164, 148},
      {164, 156},
      {164, 164},
      {164, 172},
      {164, 180},
      {164, 189},
      {164, 197},
      {164, 205},
      {164, 213},
      {164, 222},
      {164, 230},
      {164, 238},
      {164, 246},
      {164, 255}
    ],
    [
      {156, 0},
      {156, 8},
      {156, 16},
      {156, 24},
      {156, 32},
      {156, 41},
      {156, 49},
      {156, 57},
      {156, 65},
      {156, 74},
      {156, 82},
      {156, 90},
      {156, 98},
      {156, 106},
      {156, 115},
      {156, 123},
      {156, 131},
      {156, 139},
      {156, 148},
      {156, 156},
      {156, 164},
      {156, 172},
      {156, 180},
      {156, 189},
      {156, 197},
      {156, 205},
      {156, 213},
      {156, 222},
      {156, 230},
      {156, 238},
      {156, 246},
      {156, 255}
    ],
    [
      {148, 0},
      {148, 8},
      {148, 16},
      {148, 24},
      {148, 32},
      {148, 41},
      {148, 49},
      {148, 57},
      {148, 65},
      {148, 74},
      {148, 82},
      {148, 90},
      {148, 98},
      {148, 106},
      {148, 115},
      {148, 123},
      {148, 131},
      {148, 139},
      {148, 148},
      {148, 156},
      {148, 164},
      {148, 172},
      {148, 180},
      {148, 189},
      {148, 197},
      {148, 205},
      {148, 213},
      {148, 222},
      {148, 230},
      {148, 238},
      {148, 246},
      {148, 255}
    ],
    [
      {139, 0},
      {139, 8},
      {139, 16},
      {139, 24},
      {139, 32},
      {139, 41},
      {139, 49},
      {139, 57},
      {139, 65},
      {139, 74},
      {139, 82},
      {139, 90},
      {139, 98},
      {139, 106},
      {139, 115},
      {139, 123},
      {139, 131},
      {139, 139},
      {139, 148},
      {139, 156},
      {139, 164},
      {139, 172},
      {139, 180},
      {139, 189},
      {139, 197},
      {139, 205},
      {139, 213},
      {139, 222},
      {139, 230},
      {139, 238},
      {139, 246},
      {139, 255}
    ],
    [
      {131, 0},
      {131, 8},
      {131, 16},
      {131, 24},
      {131, 32},
      {131, 41},
      {131, 49},
      {131, 57},
      {131, 65},
      {131, 74},
      {131, 82},
      {131, 90},
      {131, 98},
      {131, 106},
      {131, 115},
      {131, 123},
      {131, 131},
      {131, 139},
      {131, 148},
      {131, 156},
      {131, 164},
      {131, 172},
      {131, 180},
      {131, 189},
      {131, 197},
      {131, 205},
      {131, 213},
      {131, 222},
      {131, 230},
      {131, 238},
      {131, 246},
      {131, 255}
    ],
    [
      {123, 0},
      {123, 8},
      {123, 16},
      {123, 24},
      {123, 32},
      {123, 41},
      {123, 49},
      {123, 57},
      {123, 65},
      {123, 74},
      {123, 82},
      {123, 90},
      {123, 98},
      {123, 106},
      {123, 115},
      {123, 123},
      {123, 131},
      {123, 139},
      {123, 148},
      {123, 156},
      {123, 164},
      {123, 172},
      {123, 180},
      {123, 189},
      {123, 197},
      {123, 205},
      {123, 213},
      {123, 222},
      {123, 230},
      {123, 238},
      {123, 246},
      {123, 255}
    ],
    [
      {115, 0},
      {115, 8},
      {115, 16},
      {115, 24},
      {115, 32},
      {115, 41},
      {115, 49},
      {115, 57},
      {115, 65},
      {115, 74},
      {115, 82},
      {115, 90},
      {115, 98},
      {115, 106},
      {115, 115},
      {115, 123},
      {115, 131},
      {115, 139},
      {115, 148},
      {115, 156},
      {115, 164},
      {115, 172},
      {115, 180},
      {115, 189},
      {115, 197},
      {115, 205},
      {115, 213},
      {115, 222},
      {115, 230},
      {115, 238},
      {115, 246},
      {115, 255}
    ],
    [
      {106, 0},
      {106, 8},
      {106, 16},
      {106, 24},
      {106, 32},
      {106, 41},
      {106, 49},
      {106, 57},
      {106, 65},
      {106, 74},
      {106, 82},
      {106, 90},
      {106, 98},
      {106, 106},
      {106, 115},
      {106, 123},
      {106, 131},
      {106, 139},
      {106, 148},
      {106, 156},
      {106, 164},
      {106, 172},
      {106, 180},
      {106, 189},
      {106, 197},
      {106, 205},
      {106, 213},
      {106, 222},
      {106, 230},
      {106, 238},
      {106, 246},
      {106, 255}
    ],
    [
      {98, 0},
      {98, 8},
      {98, 16},
      {98, 24},
      {98, 32},
      {98, 41},
      {98, 49},
      {98, 57},
      {98, 65},
      {98, 74},
      {98, 82},
      {98, 90},
      {98, 98},
      {98, 106},
      {98, 115},
      {98, 123},
      {98, 131},
      {98, 139},
      {98, 148},
      {98, 156},
      {98, 164},
      {98, 172},
      {98, 180},
      {98, 189},
      {98, 197},
      {98, 205},
      {98, 213},
      {98, 222},
      {98, 230},
      {98, 238},
      {98, 246},
      {98, 255}
    ],
    [
      {90, 0},
      {90, 8},
      {90, 16},
      {90, 24},
      {90, 32},
      {90, 41},
      {90, 49},
      {90, 57},
      {90, 65},
      {90, 74},
      {90, 82},
      {90, 90},
      {90, 98},
      {90, 106},
      {90, 115},
      {90, 123},
      {90, 131},
      {90, 139},
      {90, 148},
      {90, 156},
      {90, 164},
      {90, 172},
      {90, 180},
      {90, 189},
      {90, 197},
      {90, 205},
      {90, 213},
      {90, 222},
      {90, 230},
      {90, 238},
      {90, 246},
      {90, 255}
    ],
    [
      {82, 0},
      {82, 8},
      {82, 16},
      {82, 24},
      {82, 32},
      {82, 41},
      {82, 49},
      {82, 57},
      {82, 65},
      {82, 74},
      {82, 82},
      {82, 90},
      {82, 98},
      {82, 106},
      {82, 115},
      {82, 123},
      {82, 131},
      {82, 139},
      {82, 148},
      {82, 156},
      {82, 164},
      {82, 172},
      {82, 180},
      {82, 189},
      {82, 197},
      {82, 205},
      {82, 213},
      {82, 222},
      {82, 230},
      {82, 238},
      {82, 246},
      {82, 255}
    ],
    [
      {74, 0},
      {74, 8},
      {74, 16},
      {74, 24},
      {74, 32},
      {74, 41},
      {74, 49},
      {74, 57},
      {74, 65},
      {74, 74},
      {74, 82},
      {74, 90},
      {74, 98},
      {74, 106},
      {74, 115},
      {74, 123},
      {74, 131},
      {74, 139},
      {74, 148},
      {74, 156},
      {74, 164},
      {74, 172},
      {74, 180},
      {74, 189},
      {74, 197},
      {74, 205},
      {74, 213},
      {74, 222},
      {74, 230},
      {74, 238},
      {74, 246},
      {74, 255}
    ],
    [
      {65, 0},
      {65, 8},
      {65, 16},
      {65, 24},
      {65, 32},
      {65, 41},
      {65, 49},
      {65, 57},
      {65, 65},
      {65, 74},
      {65, 82},
      {65, 90},
      {65, 98},
      {65, 106},
      {65, 115},
      {65, 123},
      {65, 131},
      {65, 139},
      {65, 148},
      {65, 156},
      {65, 164},
      {65, 172},
      {65, 180},
      {65, 189},
      {65, 197},
      {65, 205},
      {65, 213},
      {65, 222},
      {65, 230},
      {65, 238},
      {65, 246},
      {65, 255}
    ],
    [
      {57, 0},
      {57, 8},
      {57, 16},
      {57, 24},
      {57, 32},
      {57, 41},
      {57, 49},
      {57, 57},
      {57, 65},
      {57, 74},
      {57, 82},
      {57, 90},
      {57, 98},
      {57, 106},
      {57, 115},
      {57, 123},
      {57, 131},
      {57, 139},
      {57, 148},
      {57, 156},
      {57, 164},
      {57, 172},
      {57, 180},
      {57, 189},
      {57, 197},
      {57, 205},
      {57, 213},
      {57, 222},
      {57, 230},
      {57, 238},
      {57, 246},
      {57, 255}
    ],
    [
      {49, 0},
      {49, 8},
      {49, 16},
      {49, 24},
      {49, 32},
      {49, 41},
      {49, 49},
      {49, 57},
      {49, 65},
      {49, 74},
      {49, 82},
      {49, 90},
      {49, 98},
      {49, 106},
      {49, 115},
      {49, 123},
      {49, 131},
      {49, 139},
      {49, 148},
      {49, 156},
      {49, 164},
      {49, 172},
      {49, 180},
      {49, 189},
      {49, 197},
      {49, 205},
      {49, 213},
      {49, 222},
      {49, 230},
      {49, 238},
      {49, 246},
      {49, 255}
    ],
    [
      {41, 0},
      {41, 8},
      {41, 16},
      {41, 24},
      {41, 32},
      {41, 41},
      {41, 49},
      {41, 57},
      {41, 65},
      {41, 74},
      {41, 82},
      {41, 90},
      {41, 98},
      {41, 106},
      {41, 115},
      {41, 123},
      {41, 131},
      {41, 139},
      {41, 148},
      {41, 156},
      {41, 164},
      {41, 172},
      {41, 180},
      {41, 189},
      {41, 197},
      {41, 205},
      {41, 213},
      {41, 222},
      {41, 230},
      {41, 238},
      {41, 246},
      {41, 255}
    ],
    [
      {32, 0},
      {32, 8},
      {32, 16},
      {32, 24},
      {32, 32},
      {32, 41},
      {32, 49},
      {32, 57},
      {32, 65},
      {32, 74},
      {32, 82},
      {32, 90},
      {32, 98},
      {32, 106},
      {32, 115},
      {32, 123},
      {32, 131},
      {32, 139},
      {32, 148},
      {32, 156},
      {32, 164},
      {32, 172},
      {32, 180},
      {32, 189},
      {32, 197},
      {32, 205},
      {32, 213},
      {32, 222},
      {32, 230},
      {32, 238},
      {32, 246},
      {32, 255}
    ],
    [
      {24, 0},
      {24, 8},
      {24, 16},
      {24, 24},
      {24, 32},
      {24, 41},
      {24, 49},
      {24, 57},
      {24, 65},
      {24, 74},
      {24, 82},
      {24, 90},
      {24, 98},
      {24, 106},
      {24, 115},
      {24, 123},
      {24, 131},
      {24, 139},
      {24, 148},
      {24, 156},
      {24, 164},
      {24, 172},
      {24, 180},
      {24, 189},
      {24, 197},
      {24, 205},
      {24, 213},
      {24, 222},
      {24, 230},
      {24, 238},
      {24, 246},
      {24, 255}
    ],
    [
      {16, 0},
      {16, 8},
      {16, 16},
      {16, 24},
      {16, 32},
      {16, 41},
      {16, 49},
      {16, 57},
      {16, 65},
      {16, 74},
      {16, 82},
      {16, 90},
      {16, 98},
      {16, 106},
      {16, 115},
      {16, 123},
      {16, 131},
      {16, 139},
      {16, 148},
      {16, 156},
      {16, 164},
      {16, 172},
      {16, 180},
      {16, 189},
      {16, 197},
      {16, 205},
      {16, 213},
      {16, 222},
      {16, 230},
      {16, 238},
      {16, 246},
      {16, 255}
    ],
    [
      {8, 0},
      {8, 8},
      {8, 16},
      {8, 24},
      {8, 32},
      {8, 41},
      {8, 49},
      {8, 57},
      {8, 65},
      {8, 74},
      {8, 82},
      {8, 90},
      {8, 98},
      {8, 106},
      {8, 115},
      {8, 123},
      {8, 131},
      {8, 139},
      {8, 148},
      {8, 156},
      {8, 164},
      {8, 172},
      {8, 180},
      {8, 189},
      {8, 197},
      {8, 205},
      {8, 213},
      {8, 222},
      {8, 230},
      {8, 238},
      {8, 246},
      {8, 255}
    ],
    [
      {0, 0},
      {0, 8},
      {0, 16},
      {0, 24},
      {0, 32},
      {0, 41},
      {0, 49},
      {0, 57},
      {0, 65},
      {0, 74},
      {0, 82},
      {0, 90},
      {0, 98},
      {0, 106},
      {0, 115},
      {0, 123},
      {0, 131},
      {0, 139},
      {0, 148},
      {0, 156},
      {0, 164},
      {0, 172},
      {0, 180},
      {0, 189},
      {0, 197},
      {0, 205},
      {0, 213},
      {0, 222},
      {0, 230},
      {0, 238},
      {0, 246},
      {0, 255}
    ]
  ]

  test "8 bit grayscale with alpha channel, black background" do
    {:ok, image} = Imagineer.load(@test_path <> "bgbn4a08.png")

    assert image.height == 32
    assert image.width == 32

    assert image.color_format == :grayscale_alpha
    assert image.compression == :zlib
    assert image.color_type == 4
    assert image.interlace_method == 0
    assert image.gamma == 1.0
    assert image.bit_depth == 8
    assert image.mask == nil
    assert image.format == :png
    assert image.mime_type == "image/png"
    assert image.palette == []
    assert image.background == {0}

    assert_pixels_match(image.pixels, @actual_pixels)

    :ok = Imagineer.write(image, @tmp_path <> "bgbn4a08_test.png")
    {:ok, image} = Imagineer.load(@tmp_path <> "bgbn4a08_test.png")

    assert image.height == 32
    assert image.width == 32

    assert image.color_format == :grayscale_alpha
    assert image.compression == :zlib
    assert image.color_type == 4
    assert image.interlace_method == 0
    assert image.gamma == 1.0
    assert image.bit_depth == 8
    assert image.mask == nil
    assert image.format == :png
    assert image.mime_type == "image/png"
    assert image.palette == []
    assert image.background == {0}

    assert_pixels_match(image.pixels, @actual_pixels)
  end

  test "16 grayscale with alpha channel, black background" do
    {:ok, image} = Imagineer.load(@test_path <> "bggn4a16.png")

    assert image.color_format == :grayscale_alpha
    assert image.bit_depth == 16
    assert image.background == {43908}

    :ok = Imagineer.write(image, @tmp_path <> "bggn4a16_test.png")
    {:ok, image} = Imagineer.load(@tmp_path <> "bggn4a16_test.png")

    assert image.color_format == :grayscale_alpha
    assert image.bit_depth == 16
    assert image.background == {43908}
  end

  test "8 rgb with alpha channel, white background" do
    {:ok, image} = Imagineer.load(@test_path <> "bgwn6a08.png")

    assert image.color_format == :rgb_alpha
    assert image.bit_depth == 8
    assert image.background == {255, 255, 255}

    :ok = Imagineer.write(image, @tmp_path <> "bgwn6a08_test.png")
    {:ok, image} = Imagineer.load(@tmp_path <> "bgwn6a08_test.png")

    assert image.color_format == :rgb_alpha
    assert image.bit_depth == 8
    assert image.background == {255, 255, 255}
  end

  test "16 rgb with alpha channel, yellow background" do
    {:ok, image} = Imagineer.load(@test_path <> "bgyn6a16.png")

    assert image.color_format == :rgb_alpha
    assert image.bit_depth == 16
    assert image.background == {65535, 65535, 0}

    :ok = Imagineer.write(image, @tmp_path <> "bgyn6a16_test.png")
    {:ok, image} = Imagineer.load(@tmp_path <> "bgyn6a16_test.png")

    assert image.color_format == :rgb_alpha
    assert image.bit_depth == 16
    assert image.background == {65535, 65535, 0}
  end

  defp assert_pixels_match(parsed_pixels, actual_pixels) do
    Enum.zip(parsed_pixels, actual_pixels)
    |> Enum.with_index()
    |> Enum.each(fn
      {{parsed, actual}, index} ->
        assert(actual == parsed, """
          row #{index + 1} is fucked
          \texpected: #{inspect(actual)}
          \tgot: #{inspect(parsed)}
        """)
    end)
  end
end
