using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

// Add a reference to System.Runtime.Serialization.
using System.Runtime.Serialization;

using System.Runtime.Serialization.Json;
using System.IO;

namespace JsonSerialization
{
    [Serializable]
    public class Customer
    {
        [DataMember] public string Name = "";
        [DataMember] public string Street = "";
        [DataMember] public string City = "";
        [DataMember] public string State = "";
        [DataMember] public string Zip = "";
        [DataMember] public Dictionary<string, string> PhoneNumbers =
            new Dictionary<string, string>();
        [DataMember] public List<string> EmailAddresses = new List<string>();
        [DataMember] public Order[] Orders = null;

        // Return the JSON serialization of the object.
        public string ToJson()
        {
            // Make the serializer.
            DataContractJsonSerializer serializer
                = new DataContractJsonSerializer(typeof(Customer));

            // Make a stream to serialize into.
            using (MemoryStream stream = new MemoryStream())
            {
                // Serialize into the stream.
                serializer.WriteObject(stream, this);

                // Return the stream as text.
                byte[] bytes = stream.ToArray();
                return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
            }
        }

        // Create a new Customer from a JSON serialization.
        public static Customer FromJson(string json)
        {
            // Make the serializer.
            DataContractJsonSerializer serializer =
                new DataContractJsonSerializer(typeof(Customer));

            // Make a stream from which to read.
            using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
            {
                // Deserialize and return the Customer object.
                return serializer.ReadObject(stream) as Customer;
            }
        }

        // Return a newline separated text representation.
        public override string ToString()
        {
            // Display the basic information.
            string result = "Customer" + Environment.NewLine;
            result += "    " + Name + Environment.NewLine;
            result += "    " + Street + Environment.NewLine;
            result += "    " + City + " " + State + " " + Zip + Environment.NewLine;

            // Display phone numbers.
            result += "    Phone Numbers:" + Environment.NewLine;
            foreach (KeyValuePair<string, string> pair in PhoneNumbers)
            {
                result += "        " + pair.Key + ": " + pair.Value + Environment.NewLine;
            }

            // Display email addresses.
            result += "    Email Addresses:" + Environment.NewLine;
            foreach (string address in EmailAddresses)
            {
                result += "        " + address + Environment.NewLine;
            }

            // Display orders.
            result += "    Orders:" + Environment.NewLine;
            foreach (Order order in Orders)
            {
                result += "        " + order.ToString() + Environment.NewLine;
            }

            return result;
        }
    }
}
