import {
  getName,
  getNativeName,
  getCode,
  validate,
  convertToIso,
  getAllNativeNames,
  getAllNames,
  getAllCodes,
} from "../localeLanguage";

import { LANGUAGES } from "../const";

const LOCALE_STRINGS = {
  iso: "tr",
  hyphen: "tr-TR",
  underscore: "tr_TR",
  period: "tr.TR",
  english: LANGUAGES.tr.name,
  native: LANGUAGES.tr.nativeName,
  name: "Wakanda",
  code: LANGUAGES.tr.code,
  invalid: "USA",
  null: null,
  caps: "TR-TR",
  empty: "",
};

describe("localeLanguage utils", () => {
  describe("convertToIso", () => {
    it("converts RFC hyphenated code to ISO code", () => {
      expect(convertToIso(LOCALE_STRINGS.hyphen)).toBe(LOCALE_STRINGS.code);
    });

    it("converts RFC underscore code to ISO code", () => {
      expect(convertToIso(LOCALE_STRINGS.underscore)).toBe(LOCALE_STRINGS.code);
    });

    it("converts period code to ISO code", () => {
      expect(convertToIso(LOCALE_STRINGS.period)).toBe(LOCALE_STRINGS.code);
    });

    it("converts capitalized code to ISO code", () => {
      expect(convertToIso(LOCALE_STRINGS.caps)).toBe(LOCALE_STRINGS.code);
    });

    it("returns null if invalid code is provided", () => {
      expect(convertToIso(LOCALE_STRINGS.invalid)).toBe(LOCALE_STRINGS.null);
    });
  });

  describe("validate", () => {
    it("returns true language code exists in the LANGUAGES object", () => {
      expect(validate(LOCALE_STRINGS.iso)).toBe(true);
    });

    it("returns false when you pass an invalid code", () => {
      expect(validate(LOCALE_STRINGS.invalid)).toBe(false);
    });

    it("returns false when you pass an null or falsey code", () => {
      expect(validate(LOCALE_STRINGS.null)).toBe(false);
    });
  });

  describe("getNativeName", () => {
    it("takes iso code and returns language name in the country's native language", () => {
      expect(getNativeName(LOCALE_STRINGS.iso)).toBe(LOCALE_STRINGS.native);
    });

    it("takes RFC hyphen code and returns name in native language", () => {
      expect(getNativeName(LOCALE_STRINGS.hyphen)).toBe(LOCALE_STRINGS.native);
    });

    it("takes RFC underscore code and returns name in native language", () => {
      expect(getNativeName(LOCALE_STRINGS.underscore)).toBe(
        LOCALE_STRINGS.native
      );
    });

    it("takes period code and returns name in native language", () => {
      expect(getNativeName(LOCALE_STRINGS.period)).toBe(LOCALE_STRINGS.native);
    });

    it("returns original value when you pass a language or code that can't be found", () => {
      expect(getNativeName(LOCALE_STRINGS.invalid)).toBe(
        LOCALE_STRINGS.invalid
      );
    });
  });

  describe("getName", () => {
    it("takes iso code and returns language name in English", () => {
      expect(getName(LOCALE_STRINGS.iso)).toBe(LOCALE_STRINGS.english);
    });

    it("takes RFC hyphen code and returns name in English", () => {
      expect(getName(LOCALE_STRINGS.hyphen)).toBe(LOCALE_STRINGS.english);
    });

    it("takes RFC underscore code and returns name in English", () => {
      expect(getName(LOCALE_STRINGS.underscore)).toBe(LOCALE_STRINGS.english);
    });

    it("takes period code and returns name in English", () => {
      expect(getName(LOCALE_STRINGS.period)).toBe(LOCALE_STRINGS.english);
    });

    it("returns original value when you pass a language or code that can't be found", () => {
      expect(getName(LOCALE_STRINGS.invalid)).toBe(LOCALE_STRINGS.invalid);
    });
  });

  describe("getCode", () => {
    it("takes English name and returns language code", () => {
      expect(getCode(LOCALE_STRINGS.english)).toBe(LOCALE_STRINGS.code);
    });

    it("takes native name and returns language code", () => {
      expect(getCode(LOCALE_STRINGS.native)).toBe(LOCALE_STRINGS.code);
    });

    it("takes a native name and returns an empty string if it can't find a locale", () => {
      expect(getCode(LOCALE_STRINGS.name)).toBe(LOCALE_STRINGS.empty);
    });
  });

  describe("getAllNativeNames", () => {
    it("returns all of the native names in our iso list", () => {
      expect(getAllNativeNames()[0]).toBe(LANGUAGES.aa.nativeName);
    });
  });

  describe("getAllNames", () => {
    it("returns all of the names in our iso list", () => {
      expect(getAllNames()[0]).toBe(LANGUAGES.aa.name);
    });
  });

  describe("getAllCodes", () => {
    it("returns all of the codes in our iso list", () => {
      expect(getAllCodes()[0]).toBe(LANGUAGES.aa.code);
    });
  });
});
