#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.Collections;
using System.Collections.Generic;
using System.IO;
using Google.ProtocolBuffers.Descriptors;

namespace Google.ProtocolBuffers.ProtoMunge
{
    /// <summary>
    /// Utility console application which takes a message descriptor and a corresponding message,
    /// and produces a new message with similar but random data. The data is the same length
    /// as the original, but with random values within appropriate bands. (For instance, a compressed
    /// integer in the range 0-127 will end up as another integer in the same range, to keep the length
    /// the same.)
    /// TODO(jonskeet): Potentially refactor to use an instance instead, making it simpler to
    /// be thread-safe for external use.
    /// </summary>
    public sealed class Program
    {
        private static readonly Random rng = new Random();

        private static int Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.Error.WriteLine("Usage: ProtoMunge <descriptor type name> <input data> <output file>");
                Console.Error.WriteLine(
                    "The descriptor type name is the fully-qualified message name, including assembly.");
                Console.Error.WriteLine(
                    "(At a future date it may be possible to do this without building the .NET assembly at all.)");
                return 1;
            }
            IMessage defaultMessage;
            try
            {
                defaultMessage = MessageUtil.GetDefaultMessage(args[0]);
            }
            catch (ArgumentException e)
            {
                Console.Error.WriteLine(e.Message);
                return 1;
            }
            try
            {
                IBuilder builder = defaultMessage.WeakCreateBuilderForType();
                byte[] inputData = File.ReadAllBytes(args[1]);
                builder.WeakMergeFrom(ByteString.CopyFrom(inputData));
                IMessage original = builder.WeakBuild();
                IMessage munged = Munge(original);
                if (original.SerializedSize != munged.SerializedSize)
                {
                    throw new Exception("Serialized sizes don't match");
                }
                File.WriteAllBytes(args[2], munged.ToByteArray());
                return 0;
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Error: {0}", e.Message);
                Console.Error.WriteLine();
                Console.Error.WriteLine("Detailed exception information: {0}", e);
                return 1;
            }
        }

        /// <summary>
        /// Munges a message recursively.
        /// </summary>
        /// <returns>A new message of the same type as the original message,
        /// but munged so that all the data is desensitised.</returns>
        private static IMessage Munge(IMessage message)
        {
            IBuilder builder = message.WeakCreateBuilderForType();
            foreach (var pair in message.AllFields)
            {
                if (pair.Key.IsRepeated)
                {
                    foreach (object singleValue in (IEnumerable) pair.Value)
                    {
                        builder.WeakAddRepeatedField(pair.Key, CheckedMungeValue(pair.Key, singleValue));
                    }
                }
                else
                {
                    builder[pair.Key] = CheckedMungeValue(pair.Key, pair.Value);
                }
            }
            IMessage munged = builder.WeakBuild();
            if (message.SerializedSize != munged.SerializedSize)
            {
                Console.WriteLine("Sub message sizes: {0}/{1}", message.SerializedSize, munged.SerializedSize);
            }
            return munged;
        }

        /// <summary>
        /// Munges a single value and checks that the length ends up the same as it was before.
        /// </summary>
        private static object CheckedMungeValue(FieldDescriptor fieldDescriptor, object value)
        {
            int currentSize = CodedOutputStream.ComputeFieldSize(fieldDescriptor.FieldType, fieldDescriptor.FieldNumber,
                                                                 value);
            object mungedValue = MungeValue(fieldDescriptor, value);
            int mungedSize = CodedOutputStream.ComputeFieldSize(fieldDescriptor.FieldType, fieldDescriptor.FieldNumber,
                                                                mungedValue);
            // Exceptions log more easily than assertions
            if (currentSize != mungedSize)
            {
                throw new Exception("Munged value had wrong size. Field type: " + fieldDescriptor.FieldType
                                    + "; old value: " + value + "; new value: " + mungedValue);
            }
            return mungedValue;
        }

        /// <summary>
        /// Munges a single value of the specified field descriptor. (i.e. if the field is
        /// actually a repeated int, this method receives a single int value to munge, and
        /// is called multiple times).
        /// </summary>
        private static object MungeValue(FieldDescriptor fieldDescriptor, object value)
        {
            switch (fieldDescriptor.FieldType)
            {
                case FieldType.SInt64:
                case FieldType.Int64:
                    return (long) MungeVarint64((ulong) (long) value);
                case FieldType.UInt64:
                    return MungeVarint64((ulong) value);
                case FieldType.SInt32:
                    return (int) MungeVarint32((uint) (int) value);
                case FieldType.Int32:
                    return MungeInt32((int) value);
                case FieldType.UInt32:
                    return MungeVarint32((uint) value);
                case FieldType.Double:
                    return rng.NextDouble();
                case FieldType.Float:
                    return (float) rng.NextDouble();
                case FieldType.Fixed64:
                    {
                        byte[] data = new byte[8];
                        rng.NextBytes(data);
                        return BitConverter.ToUInt64(data, 0);
                    }
                case FieldType.Fixed32:
                    {
                        byte[] data = new byte[4];
                        rng.NextBytes(data);
                        return BitConverter.ToUInt32(data, 0);
                    }
                case FieldType.Bool:
                    return rng.Next(2) == 1;
                case FieldType.String:
                    return MungeString((string) value);
                case FieldType.Group:
                case FieldType.Message:
                    return Munge((IMessage) value);
                case FieldType.Bytes:
                    return MungeByteString((ByteString) value);
                case FieldType.SFixed64:
                    {
                        byte[] data = new byte[8];
                        rng.NextBytes(data);
                        return BitConverter.ToInt64(data, 0);
                    }
                case FieldType.SFixed32:
                    {
                        byte[] data = new byte[4];
                        rng.NextBytes(data);
                        return BitConverter.ToInt32(data, 0);
                    }
                case FieldType.Enum:
                    return MungeEnum(fieldDescriptor, (EnumValueDescriptor) value);
                default:
                    // TODO(jonskeet): Different exception?
                    throw new ArgumentException("Invalid field descriptor");
            }
        }

        private static object MungeString(string original)
        {
            foreach (char c in original)
            {
                if (c > 127)
                {
                    throw new ArgumentException("Can't handle non-ascii yet");
                }
            }
            char[] chars = new char[original.Length];
            // Convert to pure ASCII - no control characters.
            for (int i = 0; i < chars.Length; i++)
            {
                chars[i] = (char) rng.Next(32, 127);
            }
            return new string(chars);
        }

        /// <summary>
        /// Int32 fields are slightly strange - we need to keep the sign the same way it is:
        /// negative numbers can munge to any other negative number (it'll always take
        /// 10 bytes) but positive numbers have to stay positive, so we can't use the
        /// full range of 32 bits.
        /// </summary>
        private static int MungeInt32(int value)
        {
            if (value < 0)
            {
                return rng.Next(int.MinValue, 0);
            }
            int length = CodedOutputStream.ComputeRawVarint32Size((uint) value);
            uint min = length == 1 ? 0 : 1U << ((length - 1)*7);
            uint max = length == 5 ? int.MaxValue : (1U << (length*7)) - 1;
            return (int) NextRandomUInt64(min, max);
        }

        private static uint MungeVarint32(uint original)
        {
            int length = CodedOutputStream.ComputeRawVarint32Size(original);
            uint min = length == 1 ? 0 : 1U << ((length - 1)*7);
            uint max = length == 5 ? uint.MaxValue : (1U << (length*7)) - 1;
            return (uint) NextRandomUInt64(min, max);
        }

        private static ulong MungeVarint64(ulong original)
        {
            int length = CodedOutputStream.ComputeRawVarint64Size(original);
            ulong min = length == 1 ? 0 : 1UL << ((length - 1)*7);
            ulong max = length == 10 ? ulong.MaxValue : (1UL << (length*7)) - 1;
            return NextRandomUInt64(min, max);
        }

        /// <summary>
        /// Returns a random number in the range [min, max] (both inclusive).
        /// </summary>    
        private static ulong NextRandomUInt64(ulong min, ulong max)
        {
            if (min > max)
            {
                throw new ArgumentException("min must be <= max; min=" + min + "; max = " + max);
            }
            ulong range = max - min;
            // This isn't actually terribly good at very large ranges - but it doesn't really matter for the sake
            // of this program.
            return min + (ulong) (range*rng.NextDouble());
        }

        private static object MungeEnum(FieldDescriptor fieldDescriptor, EnumValueDescriptor original)
        {
            // Find all the values which get encoded to the same size as the current value, and pick one at random
            int originalSize = CodedOutputStream.ComputeRawVarint32Size((uint) original.Number);
            List<EnumValueDescriptor> sameSizeValues = new List<EnumValueDescriptor>();
            foreach (EnumValueDescriptor candidate in fieldDescriptor.EnumType.Values)
            {
                if (CodedOutputStream.ComputeRawVarint32Size((uint) candidate.Number) == originalSize)
                {
                    sameSizeValues.Add(candidate);
                }
            }
            return sameSizeValues[rng.Next(sameSizeValues.Count)];
        }

        private static object MungeByteString(ByteString byteString)
        {
            byte[] data = new byte[byteString.Length];
            rng.NextBytes(data);
            return ByteString.CopyFrom(data);
        }
    }
}