//    CANAPE Network Testing Tool
//    Copyright (C) 2014 Context Information Security
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System.Collections;
using System.ComponentModel;
using CANAPE.DataFrames;
using System;
using CANAPE.Utils;

namespace CANAPE.NodeLibrary.Fuzzer
{
    [Serializable]
    public class RandomBitFuzzerNodeConfig : BaseRandomArrayFuzzerConfig
    {
        [LocalizedDescription("RandomBitFuzzerNodeConfig_NoConversionDescription", typeof(Properties.Resources))]
        public bool NoConversion { get; set; }
    }

    [NodeLibraryClass("RandomBitFuzzerNode", typeof(Properties.Resources),
        ConfigType = typeof(RandomBitFuzzerNodeConfig),
        Category = NodeLibraryClassCategory.Fuzzer
        )
    ]
    public class RandomBitFuzzerNode : BaseRandomArrayFuzzer<bool, RandomBitFuzzerNodeConfig>
    {
        protected override bool[] NodeToArray(DataNode node)
        {
            bool[] ret = null;
            DataValue value = node as DataValue;
            BitArray bits = null;

            if ((value != null) && (value.Value is byte[]))
            {
                bits = new BitArray((byte[])value.Value);
            }
            else
            {
                if (!Config.NoConversion)
                {
                    bits = new BitArray(node.ToArray());
                }
            }

            if (bits != null)
            {
                ret = new bool[bits.Count];

                bits.CopyTo(ret, 0);
            }

            return ret;
        }

        protected override DataFrames.DataNode ArrayToNode(bool[] array, DataFrames.DataNode node)
        {
            BitArray bits = new BitArray(array);
            byte[] data = new byte[(bits.Count + 7) / 8];

            bits.CopyTo(data, 0);

            node.ReplaceNode(data);

            return node;
        }

        protected override bool FuzzValue(BaseRandomArrayFuzzerConfig.FuzzCombinationMode mode, bool value)
        {
            return !value;
        }
    }
}
