/*
 * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.ts.tests.jaxrs.common.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Array;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Locale;
import java.util.TimeZone;

public abstract class JaxrsUtil {

    public static final//
    String readFromStream(InputStream stream) throws IOException {
        InputStreamReader isr = new InputStreamReader(stream);
        return readFromReader(isr);
    }

    public static final//
    String readFromReader(Reader reader) throws IOException {
        BufferedReader br = new BufferedReader(reader);
        String entity = br.readLine();
        br.close();
        return entity;
    }

    public static final//
    String readFromFile(File file) throws IOException {
        FileReader reader = new FileReader(file);
        return readFromReader(reader);
    }

    public static final <T> //
    String iterableToString(String separator, Iterable<T> collection) {
        if (collection != null) {
            return iterableToString(separator, collection.iterator());
        }
        return "";
    }

    public static final <T> //
    String iterableToString(String separator, Iterator<T> iterator) {
        StringBuilder sb = new StringBuilder();
        while (iterator.hasNext()) {
            T item = iterator.next();
            if (item != null) {
                String appendable = item.toString();
                sb.append(appendable);
                if (iterator.hasNext()) {
                    sb.append(separator);
                }
            }
        }
        return sb.toString();
    }

    public static final <T> //
    String enumerationToString(String separator, Enumeration<T> enumeration) {
        StringBuilder sb = new StringBuilder();
        if (enumeration != null) {
            while (enumeration.hasMoreElements()) {
                T item = enumeration.nextElement();
                if (item != null) {
                    String appendable = item.toString();
                    sb.append(appendable);
                    if (enumeration.hasMoreElements()) {
                        sb.append(separator);
                    }
                }
            }
        }
        return sb.toString();
    }

    public static final //
    String iterableToString(String separator, Object... collection) {
        StringBuilder sb = new StringBuilder();
        if (collection != null) {
            for (int i = 0; i != collection.length; i++) {
                Object item = collection[i];
                if (item != null) {
                    String appendable = item.toString();
                    sb.append(appendable);
                    if (i != collection.length - 1) {
                        sb.append(separator);
                    }
                }
            }
        }
        return sb.toString();
    }

    public static final TimeZone findTimeZoneInDate(String date) {
        StringBuilder sb = new StringBuilder();
        StringBuilder dateBuilder = new StringBuilder(date.trim()).reverse();
        int index = 0;
        char c;
        while ((c = dateBuilder.charAt(index++)) != ' ') {
            sb.append(c);
        }
        TimeZone timezone = TimeZone.getTimeZone(sb.reverse().toString());
        return timezone;
    }

    public static final String mapToString(java.util.Map<?, ?> map) {
        StringBuilder sb = new StringBuilder();
        if (map != null) {
            for (Object key : map.keySet()) {
                sb.append("[").append(key).append(" : ");
                Object value = map.get(key);
                sb.append(toString(value)).append("]");
            }
        }
        return sb.toString();
    }

    public static final DateFormat createDateFormat(TimeZone timezone) {
        SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        sdf.setTimeZone(timezone);
        return sdf;
    }

    public static String toString(Object object) {
        String to = null;
        if (object == null) {
            to = "null";
        } else if (Iterable.class.isInstance(object)) {
            to = iterableToString(" ", (Iterable<?>) object);
        } else if (Enumeration.class.isInstance(object)) {
            to = enumerationToString(" ", (Enumeration<?>) object);
        } else if (java.util.Map.class.isInstance(object)) {
            to = mapToString((java.util.Map<?, ?>) object);
        } else if (Iterator.class.isInstance(object)) {
            to = iterableToString(" ", (Iterator<?>) object);
        } else if (Array.class.isInstance(object)) {
            to = iterableToString(" ", (Object[]) object);
        } else if (object.getClass().isArray()) {
            to = primitiveArrayToString(object);
        } else {
            to = String.valueOf(object);
        }
        return to;
    }

    public static String primitiveArrayToString(Object array) {
        String to = null;
        if (array == null) {
            to = "null";
        } else if (array.getClass().isArray()) {
            String sarray = array.toString();
            if (sarray.startsWith("[I")) {
                to = Arrays.toString((int[]) array);
            } else if (sarray.startsWith("[B")) {
                to = Arrays.toString((byte[]) array);
            } else if (sarray.startsWith("[J")) {
                to = Arrays.toString((long[]) array);
            } else if (sarray.startsWith("[C")) {
                to = Arrays.toString((char[]) array);
            } else if (sarray.startsWith("[S")) {
                to = Arrays.toString((short[]) array);
            } else if (sarray.startsWith("[F")) {
                to = Arrays.toString((float[]) array);
            } else if (sarray.startsWith("[D")) {
                to = Arrays.toString((double[]) array);
            } else if (sarray.startsWith("[Z")) {
                to = Arrays.toString((boolean[]) array);
            } else if (sarray.startsWith("[L")) {
                to = Arrays.toString((Object[]) array);
            }
        } else {
            to = String.valueOf(array);
        }
        return to;
    }
}
