/*
 * 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.ignite.internal.client.impl;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.ignite.internal.client.GridClientCacheMode;
import org.apache.ignite.internal.client.GridClientNode;
import org.apache.ignite.internal.client.GridClientNodeMetrics;
import org.apache.ignite.internal.client.GridClientProtocol;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.jetbrains.annotations.Nullable;

import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_CLIENT_MODE;

/**
 * Client node implementation.
 */
public class GridClientNodeImpl implements GridClientNode {
    /** Node id. */
    private UUID nodeId;

    /** Consistent ID. */
    private Object consistentId;

    /** REST TCP server addresses. */
    private List<String> tcpAddrs = Collections.emptyList();

    /** REST TCP server host names. */
    private List<String> tcpHostNames = Collections.emptyList();

    /** Port for TCP rest binary protocol. */
    private int tcpPort;

    /** Node attributes. */
    private Map<String, Object> attrs = Collections.emptyMap();

    /** Node metrics. */
    private GridClientNodeMetrics metrics;

    /** Node caches. */
    private Map<String, GridClientCacheMode> caches = Collections.emptyMap();

    /** Connectable property. */
    private boolean connectable;

    /** Cache for REST TCP socket addresses. */
    private final AtomicReference<Collection<InetSocketAddress>> tcpSockAddrs = new AtomicReference<>();

    /** Node order within grid topology */
    private long order;

    /**
     * Default constructor (private).
     */
    private GridClientNodeImpl() {
        // No-op.
    }

    /**
     * Creates and returns a builder for a new instance
     * of this class.
     *
     * @return Builder for new instance.
     */
    public static Builder builder() {
        return new Builder(new GridClientNodeImpl());
    }

    /**
     * Creates and returns a builder for a new instance
     * of this class, copying data from an input instance.
     *
     * @param from Instance to copy data from.
     * @param skipAttrs Whether to skip attributes.
     * @param skipMetrics Whether to skip metrics.
     * @return Builder for new instance.
     */
    public static Builder builder(GridClientNode from, boolean skipAttrs, boolean skipMetrics) {
        Builder b = new Builder(new GridClientNodeImpl())
            .nodeId(from.nodeId())
            .consistentId(from.consistentId())
            .tcpAddresses(from.tcpAddresses())
            .tcpPort(from.tcpPort())
            .caches(from.caches())
            .connectable(from.connectable())
            .order(from.order());

        if (!skipAttrs)
            b.attributes(from.attributes());

        if (!skipMetrics)
            b.metrics(from.metrics());

        return b;
    }

    /** {@inheritDoc} */
    @Override public UUID nodeId() {
        return nodeId;
    }

    /** {@inheritDoc} */
    @Override public Object consistentId() {
        return consistentId;
    }

    /** {@inheritDoc} */
    @Override public List<String> tcpAddresses() {
        return tcpAddrs;
    }

    /** {@inheritDoc} */
    @Override public List<String> tcpHostNames() {
        return tcpHostNames;
    }

    /** {@inheritDoc} */
    @Override public int tcpPort() {
        return tcpPort;
    }

    /** {@inheritDoc} */
    @Override public Map<String, Object> attributes() {
        return Collections.unmodifiableMap(attrs);
    }

    /** {@inheritDoc} */
    @Nullable @Override public <T> T attribute(String name) {
        return (T)attrs.get(name);
    }

    /** {@inheritDoc} */
    @Override public GridClientNodeMetrics metrics() {
        return metrics;
    }

    /** {@inheritDoc} */
    @Override public Map<String, GridClientCacheMode> caches() {
        return caches;
    }

    /** {@inheritDoc} */
    @Override public Collection<InetSocketAddress> availableAddresses(GridClientProtocol proto,
        boolean filterResolved) {
        Collection<String> addrs;
        Collection<String> hostNames;
        AtomicReference<Collection<InetSocketAddress>> addrsCache;
        final int port;

        if (proto == GridClientProtocol.TCP) {
            addrsCache = tcpSockAddrs;
            addrs = tcpAddrs;
            hostNames = tcpHostNames;
            port = tcpPort;
        }
        else
            throw new AssertionError("Unknown protocol: " + proto);

        Collection<InetSocketAddress> addrs0 = addrsCache.get();

        if (addrs0 != null)
            return filterIfNecessary(addrs0, filterResolved);

        addrs0 = U.toSocketAddresses(addrs, hostNames, port);

        if (!addrsCache.compareAndSet(null, addrs0))
            return filterIfNecessary(addrsCache.get(), filterResolved);

        return filterIfNecessary(addrs0, filterResolved);
    }

    /** {@inheritDoc} */
    @Override public long order() {
        return order;
    }

    /**
     * Filters sockets with resolved addresses.
     *
     * @param addrs Addresses to filter.
     * @param filter Flag indicating whether filter should be applied or not.
     * @return Collection copy without unresolved addresses if flag is set and collection itself otherwise.
     */
    private Collection<InetSocketAddress> filterIfNecessary(Collection<InetSocketAddress> addrs, boolean filter) {
        if (!filter)
            return addrs;

        List<InetSocketAddress> res = new ArrayList<>(addrs.size());

        for (InetSocketAddress addr : addrs)
            if (!addr.isUnresolved())
                res.add(addr);

        return res;
    }

    /** {@inheritDoc} */
    @Override public boolean connectable() {
        return connectable;
    }

    /** {@inheritDoc} */
    @Override public boolean equals(Object o) {
        if (this == o) return true;

        if (!(o instanceof GridClientNodeImpl)) return false;

        GridClientNodeImpl that = (GridClientNodeImpl)o;

        return nodeId.equals(that.nodeId);
    }

    /** {@inheritDoc} */
    @Override public boolean isClient() {
        return Objects.equals(attribute(ATTR_CLIENT_MODE), true);
    }

    /** {@inheritDoc} */
    @Override public int hashCode() {
        return nodeId.hashCode();
    }

    /** {@inheritDoc} */
    @Override public String toString() {
        return "GridClientNodeImpl [nodeId=" + nodeId +
            ", consistentId=" + consistentId +
            ", tcpAddrs=" + tcpAddrs +
            ", tcpHostNames=" + tcpHostNames +
            ", binaryPort=" + tcpPort +
            ']';
    }

    /**
     * Builder for instances of this class.
     */
    @SuppressWarnings("PublicInnerClass")
    public static final class Builder {
        /** */
        private GridClientNodeImpl impl;

        /** */
        private boolean built;

        /**
         * @param impl Implementation reference to build.
         */
        private Builder(GridClientNodeImpl impl) {
            this.impl = impl;
        }

        /**
         * Finishes instance construction and returns a
         * newly-built instance.
         *
         * @return A newly-built instance.
         */
        public GridClientNodeImpl build() {
            if (built)
                throw new AssertionError("Instance already built.");

            built = true;

            return impl;
        }

        /**
         * Sets node ID.
         *
         * @param nodeId Node ID.
         * @return This for chaining.
         */
        public Builder nodeId(UUID nodeId) {
            impl.nodeId = nodeId;

            return this;
        }

        /**
         * Sets node consistent ID.
         *
         * @param consistentId New consistent ID.
         * @return This for chaining.
         */
        public Builder consistentId(Object consistentId) {
            impl.consistentId = consistentId;

            return this;
        }

        /**
         * Sets list of REST TCP server addresses.
         *
         * @param tcpAddrs List of address strings.
         * @return This for chaining.
         */
        public Builder tcpAddresses(Collection<String> tcpAddrs) {
            impl.tcpAddrs = U.sealList(tcpAddrs);

            return this;
        }

        /**
         * Sets list of REST TCP server host names.
         *
         * @param tcpHostNames List of host names.
         * @return This for chaining.
         */
        public Builder tcpHostNames(Collection<String> tcpHostNames) {
            impl.tcpHostNames = U.sealList(tcpHostNames);

            return this;
        }

        /**
         * Sets remote TCP port value.
         *
         * @param tcpPort Sets remote port value.
         * @return This for chaining.
         */
        public Builder tcpPort(int tcpPort) {
            impl.tcpPort = tcpPort;

            return this;
        }

        /**
         * Sets node attributes.
         *
         * @param attrs Node attributes.
         * @return This for chaining.
         */
        public Builder attributes(Map<String, Object> attrs) {
            impl.attrs = U.sealMap(attrs);

            return this;
        }

        /**
         * Sets node metrics.
         *
         * @param metrics Metrics.
         * @return This for chaining.
         */
        public Builder metrics(GridClientNodeMetrics metrics) {
            impl.metrics = metrics;

            return this;
        }

        /**
         * Sets caches available on remote node.
         *
         * @param caches Cache map.
         * @return This for chaining.
         */
        public Builder caches(Map<String, GridClientCacheMode> caches) {
            impl.caches = U.sealMap(caches);

            return this;
        }

        /**
         * Sets connectable property.
         *
         * @param connectable Connectable value.
         * @return This for chaining.
         */
        public Builder connectable(boolean connectable) {
            impl.connectable = connectable;

            return this;
        }

        /**
         * Set node order within grid topology
         *
         * @param order Node order within grid topology
         */
        public Builder order(long order) {
            impl.order = order;

            return this;
        }
    }
}
