package igw_test

import (
	"archive/zip"
	"bytes"
	"io"
	"strings"
	"testing"

	"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/nsdadapter/igw"
)

// TestPackXML_StructureMatchesSpec — после упаковки в ZIP должны быть
// ровно два файла: doc.xml + config.xml. Config содержит <name> и
// <package>. Это структура из раздела 2.3 инструкции НРД.
func TestPackXML_StructureMatchesSpec(t *testing.T) {
	xmlBody := []byte(`<?xml version="1.0" encoding="windows-1251"?><rt:M2MTransferRequest/>`)
	zipBytes, err := igw.PackXML(xmlBody, "M2MTransferRequest.xml", "#M2MTR")
	if err != nil {
		t.Fatal(err)
	}
	r, err := zip.NewReader(bytes.NewReader(zipBytes), int64(len(zipBytes)))
	if err != nil {
		t.Fatal(err)
	}
	if len(r.File) != 2 {
		t.Fatalf("в ZIP должно быть 2 файла, получено %d", len(r.File))
	}
	got := map[string][]byte{}
	for _, f := range r.File {
		rc, _ := f.Open()
		b, _ := io.ReadAll(rc)
		rc.Close()
		got[f.Name] = b
	}
	if _, ok := got["M2MTransferRequest.xml"]; !ok {
		t.Errorf("в ZIP нет M2MTransferRequest.xml. Файлы: %v", keys(got))
	}
	cfg, ok := got["config.xml"]
	if !ok {
		t.Fatalf("в ZIP нет config.xml. Файлы: %v", keys(got))
	}
	cfgStr := string(cfg)
	if !strings.Contains(cfgStr, "<name>M2MTransferRequest.xml</name>") {
		t.Errorf("config.xml не содержит правильное <name>: %s", cfgStr)
	}
	if !strings.Contains(cfgStr, "<package>#M2MTR</package>") {
		t.Errorf("config.xml не содержит правильное <package>: %s", cfgStr)
	}
}

func TestPackXML_RejectsBadPackageType(t *testing.T) {
	_, err := igw.PackXML([]byte("<x/>"), "doc.xml", "M2MTR")
	if err == nil {
		t.Fatal("ожидалась ошибка для packageType без #")
	}
}

// TestUnpackPackage_FindsXMLAndWinf — распаковка эмулирует входящий ZIP
// от ИШ: M2MTD.xml + winf.xml + .sgn. Проверяем что UnpackPackage
// корректно раскладывает по полям.
func TestUnpackPackage_FindsXMLAndWinf(t *testing.T) {
	docBody := []byte("<dn:M2MTransferDecision/>")
	winfBody := []byte("<winf/>")
	sgnBody := []byte("BINARY-SIGN-BLOB")

	var buf bytes.Buffer
	w := zip.NewWriter(&buf)
	must := func(name string, data []byte) {
		fw, _ := w.Create(name)
		_, _ = fw.Write(data)
	}
	must("M2MTD20260320140624.XML", docBody)
	must("winf.xml", winfBody)
	must("M2MTD20260320140624.XML.sgn", sgnBody)
	_ = w.Close()

	pkg, err := igw.UnpackPackage(buf.Bytes())
	if err != nil {
		t.Fatal(err)
	}
	if string(pkg.DocXML) != string(docBody) {
		t.Errorf("DocXML mismatch")
	}
	if string(pkg.WinfXML) != string(winfBody) {
		t.Errorf("WinfXML mismatch")
	}
	if string(pkg.Signature) != string(sgnBody) {
		t.Errorf("Signature mismatch")
	}
	if len(pkg.Filenames) != 3 {
		t.Errorf("ожидалось 3 файла в Filenames, получено %d", len(pkg.Filenames))
	}
}

func TestUnpackPackage_EmptyXML(t *testing.T) {
	var buf bytes.Buffer
	w := zip.NewWriter(&buf)
	fw, _ := w.Create("winf.xml")
	_, _ = fw.Write([]byte("<winf/>"))
	_ = w.Close()
	_, err := igw.UnpackPackage(buf.Bytes())
	if err == nil {
		t.Fatal("ожидалась ошибка когда в ZIP нет основного .xml")
	}
}

func keys(m map[string][]byte) []string {
	out := make([]string, 0, len(m))
	for k := range m {
		out = append(out, k)
	}
	return out
}
