﻿#region Copyright notice and license

// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#endregion

using System;
using System.IO;
using Google.Protobuf;

namespace Google.ProtocolBuffers.Examples.AddressBook
{
    internal class AddPerson
    {
        /// <summary>
        /// Builds a person based on user input
        /// </summary>
        private static Person PromptForAddress(TextReader input, TextWriter output)
        {
            Person person = new Person();

            output.Write("Enter person ID: ");
            person.Id = int.Parse(input.ReadLine());

            output.Write("Enter name: ");
            person.Name = input.ReadLine();

            output.Write("Enter email address (blank for none): ");
            string email = input.ReadLine();
            if (email.Length > 0)
            {
                person.Email = email;
            }

            while (true)
            {
                output.Write("Enter a phone number (or leave blank to finish): ");
                string number = input.ReadLine();
                if (number.Length == 0)
                {
                    break;
                }

                Person.Types.PhoneNumber phoneNumber = new Person.Types.PhoneNumber { Number = number };

                output.Write("Is this a mobile, home, or work phone? ");
                String type = input.ReadLine();
                switch (type)
                {
                    case "mobile":
                        phoneNumber.Type = Person.Types.PhoneType.MOBILE;
                        break;
                    case "home":
                        phoneNumber.Type = Person.Types.PhoneType.HOME;
                        break;
                    case "work":
                        phoneNumber.Type = Person.Types.PhoneType.WORK;
                        break;
                    default:
                        output.Write("Unknown phone type. Using default.");
                        break;
                }

                person.Phone.Add(phoneNumber);
            }
            return person;
        }

        /// <summary>
        /// Entry point - loads an existing addressbook or creates a new one,
        /// then writes it back to the file.
        /// </summary>
        public static int Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.Error.WriteLine("Usage:  AddPerson ADDRESS_BOOK_FILE");
                return -1;
            }

            AddressBook addressBook;

            if (File.Exists(args[0]))
            {
                using (Stream file = File.OpenRead(args[0]))
                {
                    addressBook = AddressBook.Parser.ParseFrom(file);
                }
            }
            else
            {
                Console.WriteLine("{0}: File not found. Creating a new file.", args[0]);
                addressBook = new AddressBook();
            }

            // Add an address.
            addressBook.Person.Add(PromptForAddress(Console.In, Console.Out));

            // Write the new address book back to disk.
            using (Stream output = File.OpenWrite(args[0]))
            {
                addressBook.WriteTo(output);
            }
            return 0;
        }
    }
}