/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.fleece.mapper;

import org.junit.Test;

import java.io.StringReader;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Comparator;

import static org.junit.Assert.assertEquals;

public class LiteralTest {
    @Test
    public void writeReadNumbers() {
        NumberClass nc = new NumberClass();
        final StringWriter sw = new StringWriter();
        nc.setBg(new BigDecimal("123.123"));
        nc.setBi(new BigInteger("123"));
        nc.setDoubleNumber(123.123);
        nc.setBool(true);
        nc.setByteNumber((byte) 1);
        nc.setFloatNumber(123);
        nc.setShortNumber((short) 1);
        nc.setLongNumber(123L);
        nc.setIntNumber(123);

        final String expectedJson = "{\"shortNumber\":1,\"byteNumber\":1,\"intNumber\":123,\"floatNumber\":123.0,\"bg\":123.123,\"bool\":true,\"bi\":123,\"longNumber\":123,\"doubleNumber\":123.123}";
        final Comparator<String> attributeOrder = new Comparator<String>() {
            @Override
            public int compare(final String o1, final String o2) {
                return expectedJson.indexOf(o1) - expectedJson.indexOf(o2);
            }
        };
        new MapperBuilder().setAttributeOrder(attributeOrder).build().writeObject(nc, sw);
        assertEquals(expectedJson, sw.toString());
        final NumberClass read = new MapperBuilder().setAttributeOrder(attributeOrder).build()
                    .readObject(new StringReader(sw.toString()), NumberClass.class);
        assertEquals(nc, read);

    }

    @Test(expected = NumberFormatException.class)
    public void writeReadNumbersInf() {
        NumberClass nc = new NumberClass();
        final StringWriter sw = new StringWriter();
        nc.setBg(new BigDecimal("123.123"));
        nc.setBi(new BigInteger("123"));
        nc.setDoubleNumber(Double.POSITIVE_INFINITY);
        nc.setBool(true);
        nc.setByteNumber((byte) 1);
        nc.setFloatNumber(123);
        nc.setShortNumber((short) 1);
        nc.setLongNumber(123L);
        nc.setIntNumber(123);

        new MapperBuilder().build().writeObject(nc, sw);

    }

    @Test(expected = NumberFormatException.class)
    public void writeReadNumbersNaN() {
        NumberClass nc = new NumberClass();
        final StringWriter sw = new StringWriter();
        nc.setBg(new BigDecimal("123.123"));
        nc.setBi(new BigInteger("123"));
        nc.setDoubleNumber(Double.NaN);
        nc.setBool(true);
        nc.setByteNumber((byte) 1);
        nc.setFloatNumber(123);
        nc.setShortNumber((short) 1);
        nc.setLongNumber(123L);
        nc.setIntNumber(123);

        new MapperBuilder().build().writeObject(nc, sw);

    }

    public static class NumberClass {
        private BigDecimal bg;
        private BigInteger bi;
        private int intNumber;
        private long longNumber;
        private byte byteNumber;
        private short shortNumber;
        private double doubleNumber;
        private float floatNumber;
        private boolean bool;

        public BigDecimal getBg() {
            return bg;
        }

        public void setBg(BigDecimal bg) {
            this.bg = bg;
        }

        public BigInteger getBi() {
            return bi;
        }

        public void setBi(BigInteger bi) {
            this.bi = bi;
        }

        public int getIntNumber() {
            return intNumber;
        }

        public void setIntNumber(int intNumber) {
            this.intNumber = intNumber;
        }

        public long getLongNumber() {
            return longNumber;
        }

        public void setLongNumber(long longNumber) {
            this.longNumber = longNumber;
        }

        public byte getByteNumber() {
            return byteNumber;
        }

        public void setByteNumber(byte byteNumber) {
            this.byteNumber = byteNumber;
        }

        public short getShortNumber() {
            return shortNumber;
        }

        public void setShortNumber(short shortNumber) {
            this.shortNumber = shortNumber;
        }

        public double getDoubleNumber() {
            return doubleNumber;
        }

        public void setDoubleNumber(double doubleNumber) {
            this.doubleNumber = doubleNumber;
        }

        public float getFloatNumber() {
            return floatNumber;
        }

        public void setFloatNumber(float floatNumber) {
            this.floatNumber = floatNumber;
        }

        public boolean isBool() {
            return bool;
        }

        public void setBool(boolean bool) {
            this.bool = bool;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((bg == null) ? 0 : bg.hashCode());
            result = prime * result + ((bi == null) ? 0 : bi.hashCode());
            result = prime * result + (bool ? 1231 : 1237);
            result = prime * result + byteNumber;
            long temp;
            temp = Double.doubleToLongBits(doubleNumber);
            result = prime * result + (int) (temp ^ (temp >>> 32));
            result = prime * result + Float.floatToIntBits(floatNumber);
            result = prime * result + intNumber;
            result = prime * result + (int) (longNumber ^ (longNumber >>> 32));
            result = prime * result + shortNumber;
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            NumberClass other = (NumberClass) obj;
            if (bg == null) {
                if (other.bg != null) {
                    return false;
                }
            } else if (!bg.equals(other.bg)) {
                return false;
            }
            if (bi == null) {
                if (other.bi != null) {
                    return false;
                }
            } else if (!bi.equals(other.bi)) {
                return false;
            }
            if (bool != other.bool) {
                return false;
            }
            if (byteNumber != other.byteNumber) {
                return false;
            }
            if (Double.doubleToLongBits(doubleNumber) != Double.doubleToLongBits(other.doubleNumber)) {
                return false;
            }
            if (Float.floatToIntBits(floatNumber) != Float.floatToIntBits(other.floatNumber)) {
                return false;
            }
            if (intNumber != other.intNumber) {
                return false;
            }
            if (longNumber != other.longNumber) {
                return false;
            }
            if (shortNumber != other.shortNumber) {
                return false;
            }
            return true;
        }

        @Override
        public String toString() {
            return "NumberClass [bg=" + bg + ", bi=" + bi + ", intNumber=" + intNumber + ", longNumber=" + longNumber + ", byteNumber=" + byteNumber + ", shortNumber=" + shortNumber + ", doubleNumber=" + doubleNumber + ", floatNumber=" + floatNumber + ", bool=" + bool + "]";
        }
    }
}
