const enrich = require("../main");
const expect = require('chai').expect;
const fs = require("fs");
const raw = fs.readFileSync(__dirname + "/hojin.txt", "UTF-8");
const seikai = {};

//法人番号公表サイトから取得した、 法人番号と法人種別のペア
fs.readFileSync(__dirname + "/expected.txt", "UTF-8").split("\n").forEach(a => {
  const b = a.split(",");
  if (b.length === 2) seikai[b[0]] = b[1];
});

let output = "法人番号,表記,組織種別,組織種別位置,種別,説明,法人番号公表サイトにおける組織種別\n";


describe('imi-enrichment-hojin', function() {

  describe('stat', function() {
    const score = {
      start: new Date().getTime(),
      total: 0
    };

    const added = {
      "組織種別": 0,
      "組織種別位置": 0
    };
    const types = {};

    const seigo = {
      "正解": 0,
      "誤判定": 0,
      "種別なし(複数法人)": 0,
      "種別なし(自治体・国の機関等)": 0,
      "種別なし": 0,
      "存在しない法人番号": 0
    };

    raw.split("\n").filter((a, i) => a.length > 0).forEach(line => {
      const cols = line.split(",");
      score.total++;
      const input = {
        "@context": "https://imi.go.jp/ns/core/context.jsonld",
        "@type": "法人型",
        "表記": cols[1],
        "ID": {
          "@type": "ID型",
          "ID体系": {
            "@type": "ID体系型",
            "表記": "国税庁法人番号"
          },
          "識別値": cols[0]
        }
      };

      const result = enrich(input);
      if (result["組織種別"] !== undefined) added["組織種別"]++;
      if (result["組織種別位置"] !== undefined) added["組織種別位置"]++;

      let key = "";
      if (result["組織種別"]) key += `${result["組織種別"]["識別値"]}:${result["組織種別"]["表記"]}`;
      if (result["組織種別位置"]) key += `(${result["組織種別位置"]})`;
      if (key.length === 0) key = "判定不能";
      if (types[key] === undefined) types[key] = 0;
      types[key]++;

      const expected = seikai[cols[0]];
      if (expected === undefined) {
        seigo["存在しない法人番号"]++;
      } else if (result["組織種別"] === undefined) {
        if (result["メタデータ"]["説明"].indexOf("複数") !== -1)
          seigo["種別なし(複数法人)"]++;
        else if (expected.indexOf("3") !== 0) {
          seigo["種別なし(自治体・国の機関等)"]++;
        } else {
          seigo["種別なし"]++;
        }
      } else if (result["組織種別"]["識別値"] === expected) {
        seigo["正解"]++;
      } else {
        seigo["誤判定"]++;
      }

      const row = [
        result["ID"]["識別値"] || "",
        result["表記"] || "",
        result["組織種別"] ? result["組織種別"]["識別値"] : "",
        result["組織種別位置"] || "",
        result["メタデータ"]["種別"] || "",
        result["メタデータ"]["説明"] || "",
        expected || "該当法人番号なし"
      ];

      output += row.join(",") + "\n";
    });

    require("fs").writeFileSync(__dirname + "/output.csv", '\uFEFF' + output, "UTF-8");

    score.end = new Date().getTime();
    score.duration = score.end - score.start;
    score.average = score.duration / score.total;

    describe("全体", () => {
      it(`入力件数: ${score.total} (${(score.total/score.total*100).toFixed(2)}%)`, () => {
        expect(score.total).to.equal(196551);
      });
      it(`実行時間: ${score.duration} [msec]`, () => {
        expect(score.duration).to.be.below(60 * 1000);
      });
      it(`10,000件あたり: ${(score.duration / score.total * 10000).toFixed(2)} [msec]`, () => {
        expect(score.duration / score.total * 10000).to.be.below(2000);
      });
    });

    describe("付与されたプロパティ", () => {
      const a = {
        "組織種別": 190198,
        "組織種別位置": 187749
      };
      Object.keys(a).forEach(key => {
        it(`${key}: ${added[key]} (${(added[key]/score.total*100).toFixed(2)}%)`, () => {
          expect(added[key]).to.equal(a[key]);
        });
      });
    });

    describe("分類", () => {
      const a = {
        "301:株式会社(前)": 76573,
        "301:株式会社(後)": 52863,
        "301:株式会社": 1916,
        "302:有限会社(前)": 18004,
        "302:有限会社(後)": 1639,
        "302:有限会社": 33,
        "303:合名会社(前)": 70,
        "303:合名会社(後)": 27,
        "305:合同会社(前)": 759,
        "305:合同会社(後)": 476,
        "305:合同会社": 23,
        "304:合資会社(前)": 309,
        "304:合資会社(後)": 58,
        "304:合資会社": 2,
        "399:その他の設立登記法人(前)": 29977,
        "399:その他の設立登記法人(後)": 6994,
        "399:その他の設立登記法人": 475,
        "判定不能": 6353
      };
      Object.keys(a).forEach(key => {
        it(`${key}: ${types[key]} (${(types[key]/score.total*100).toFixed(2)}%)`, () => {
          expect(types[key]).to.equal(a[key]);
        });
      });
    });

    describe("正誤判定", () => {
      const a = {
        '正解': 188434,
        '誤判定': 1119,
        '種別なし(複数法人)': 397,
        "種別なし(自治体・国の機関等)": 4544,
        '種別なし': 1316,
        '存在しない法人番号': 741
      };
      Object.keys(a).forEach(key => {
        it(`${key}: ${seigo[key]} (${(seigo[key]/score.total*100).toFixed(2)}%)`, () => {
          expect(seigo[key]).to.equal(a[key]);
        });
      });
    });




  });
});
