using System.Xml.Serialization; // XmlSerializer
using BibliotekaWspolna; // Osoba

using NowaJson = System.Text.Json.JsonSerializer;

using static System.Console;
using static System.Environment;
using static System.IO.Path;

// tworzenie hierarchii obiektów
List<Osoba> osoby = new()
{
  new(30000M)
  {
    Imie = "Alicja",
    Nazwisko = "Nowak",
    DataUrodzenia = new(1974, 3, 14)
  },
  new(40000M)
  {
    Imie = "Bartosz",
    Nazwisko = "Kowalski",
    DataUrodzenia = new(1969, 11, 23)
  },
  new(20000M)
  {
    Imie = "Celina",
    Nazwisko = "Rozenek",
    DataUrodzenia = new(1984, 5, 4),
    Dzieci = new()
    {
      new(0M)
      {
        Imie = "Anita",
        Nazwisko = "Rozenek",
        DataUrodzenia = new(2000, 7, 12)
      }
    }
  }
};

// tworzenie obiektu, który zapisze listę osób do pliku XML
XmlSerializer xs = new(osoby.GetType());

// tworzenie i zapisywanie pliku
string sciezka = Combine(CurrentDirectory, "osoby.xml");

using (FileStream strumien = File.Create(sciezka))
{
   // serializowanie hierarchii obiektów do strumienia
   xs.Serialize(strumien, osoby);
}

WriteLine("Zapisano {0} bajtów danych XML do {1}",
   arg0: new FileInfo(sciezka).Length,
   arg1: sciezka);
WriteLine();

// wyświetlenie zserializowanej hierarchii
WriteLine(File.ReadAllText(sciezka));

// Deserializowanie XML
using (FileStream odczytaneXml = File.Open(sciezka, FileMode.Open))
{
   // deserializacja i rzutowanie hierarchii obiektów
   List<Osoba> odczytaneOsoby =
      xs.Deserialize(odczytaneXml) as List<Osoba>;

   if (odczytaneOsoby is not null)
   {
      foreach (Osoba os in odczytaneOsoby)
      {
         WriteLine("{0} ma {1} dzieci.",
            os.Nazwisko, os.Dzieci.Count);
      }
   }
}


// tworzenie pliku, do którego będziemy zapisywać
string sciezkaJson = Combine(CurrentDirectory, "osoby.json");

using (StreamWriter strumienJson = File.CreateText(sciezkaJson))
{
   // tworzenie obiektu, który będzie zapisywał dane w formacie JSON
   Newtonsoft.Json.JsonSerializer jss = new();

   // serializowanie hierarchii obiektów do ciągu znaków
   jss.Serialize(strumienJson, osoby);
}
WriteLine();
WriteLine("Zapisano {0:N0} bajtów danych w formacie JSON do pliku: {1}",
   arg0: new FileInfo(sciezkaJson).Length,
   arg1: sciezkaJson);

// wyświetlenie zserializowanej hierarchii obiektów
WriteLine(File.ReadAllText(sciezkaJson));


// Deserializowanie za pomocą nowego API JSON
using (FileStream daneJson = File.Open(sciezka, FileMode.Open))
{
   // deserializacja grafu obiektów do typu List<Osoba>
   List<Osoba>? listaOsob =
      await NowaJson.DeserializeAsync(utf8Json: daneJson,
        returnType: typeof(List<Osoba>)) as List<Osoba>;

   if (listaOsob is not null)
   {
      foreach (var osoba in listaOsob)
      {
         WriteLine("{0} ma {1} dzieci.",
            osoba.Nazwisko, osoba.Dzieci?.Count);
      }
   }
}
