/*
 * Copyright (C) 2023 StApps
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */

/* eslint-disable @typescript-eslint/no-explicit-any,jsdoc/require-jsdoc,@typescript-eslint/no-non-null-assertion */
import english from '../../assets/i18n/en.json';
import german from '../../assets/i18n/de.json';

const exceptions = new Set(
  [
    'login',
    'ok',
    'protein',
    'feedback',
    'name',
    'status',
    'issn',
    'ejournal',
    'backup',
    'export',
    'dashboard',
    'home',
    'email',
    'logins',
    'google maps',
    'apple maps',
    'openstreetmaps routing',
    'https://www.swffm.de/essen-trinken/uebersicht/umweltscore',
    'https://www.google.com/maps/dir/?api=1&destination={{lat}},{{lon}}&origin={{posLat}},{{posLon}}',
    'https://maps.apple.com/?daddr={{lat}},{{lon}}&saddr={{posLat}},{{posLon}}',
    'https://www.openstreetmap.org/directions?from={{posLat}},{{posLon}}&to={{lat}},{{lon}}#map=15/{{lat}}/{{lon}}',
  ].map(it => it.toLowerCase()),
);

const languages = [
  ['english', english],
  ['german', german],
] as [string, any][];

describe('i18n', function () {
  for (const [name, language] of languages) {
    const [targetName, target] = languages.find(([target]) => target !== name)!;

    describe(`${name} (compare to ${targetName})`, function () {
      it('should have translations for all languages', function () {
        traverseCompare(target, language, (a, b, path) => {
          expect(typeof b).toBe(typeof a, `Missing translation for ${path.join('.')}`);
        });
      });

      it('should have unique translations for each language', function () {
        traverseCompare(target, language, (a, b, path) => {
          if (!exceptions.has(a.toLowerCase())) {
            expect(b).not.toBe(
              a,
              `Do not copy translations (${path.join(
                '.',
              )}). If this is a mistake, add an exception in 'src/app/translation/i18n.spec.ts'`,
            );
          }
        });
      });
    });
  }
});

function traverseCompare(
  a: any,
  b: any,
  compare: (a: any, b: any, path: string[]) => void,
  path: string[] = [],
) {
  for (const key of Object.keys(a)) {
    if (typeof a[key] === 'object') {
      traverseCompare(a[key], b[key], compare, [...path, key]);
    } else {
      compare(a[key], b[key], [...path, key]);
    }
  }
}
