/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed 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.onosproject.ui.impl;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
import org.onlab.packet.IpAddress;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Host;
import org.onosproject.net.host.HostService;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.table.CellFormatter;
import org.onosproject.ui.table.TableModel;
import org.onosproject.ui.table.TableRequestHandler;
import org.onosproject.ui.table.cell.HostLocationFormatter;

import java.util.Collection;
import java.util.Set;

import static com.google.common.base.Strings.isNullOrEmpty;

/**
 * Message handler for host view related messages.
 */
public class HostViewMessageHandler extends UiMessageHandler {

    private static final String HOST_DATA_REQ = "hostDataRequest";
    private static final String HOST_DATA_RESP = "hostDataResponse";
    private static final String HOSTS = "hosts";

    private static final String TYPE_IID = "_iconid_type";
    private static final String ID = "id";
    private static final String MAC = "mac";
    private static final String VLAN = "vlan";
    private static final String IPS = "ips";
    private static final String LOCATION = "location";

    private static final String HOST_ICON_PREFIX = "hostIcon_";

    private static final String[] COL_IDS = {
            TYPE_IID, ID, MAC, VLAN, IPS, LOCATION
    };

    @Override
    protected Collection<RequestHandler> createRequestHandlers() {
        return ImmutableSet.of(new HostDataRequest());
    }

    // handler for host table requests
    private final class HostDataRequest extends TableRequestHandler {
        private HostDataRequest() {
            super(HOST_DATA_REQ, HOST_DATA_RESP, HOSTS);
        }

        @Override
        protected String[] getColumnIds() {
            return COL_IDS;
        }

        @Override
        protected TableModel createTableModel() {
            TableModel tm = super.createTableModel();
            tm.setFormatter(LOCATION, HostLocationFormatter.INSTANCE);
            tm.setFormatter(IPS, new IpSetFormatter());
            return tm;
        }

        @Override
        protected void populateTable(TableModel tm, ObjectNode payload) {
            HostService hs = get(HostService.class);
            for (Host host : hs.getHosts()) {
                populateRow(tm.addRow(), host);
            }
        }

        private void populateRow(TableModel.Row row, Host host) {
            row.cell(TYPE_IID, getTypeIconId(host))
                    .cell(ID, host.id())
                    .cell(MAC, host.mac())
                    .cell(VLAN, host.vlan())
                    .cell(IPS, host.ipAddresses())
                    .cell(LOCATION, host.location());
        }

        private String getTypeIconId(Host host) {
            String hostType = host.annotations().value(AnnotationKeys.TYPE);
            return HOST_ICON_PREFIX +
                    (isNullOrEmpty(hostType) ? "endstation" : hostType);
        }

        private final class IpSetFormatter implements CellFormatter {
            private static final String COMMA = ", ";

            @Override
            public String format(Object value) {
                Set<IpAddress> ips = (Set<IpAddress>) value;
                if (ips.isEmpty()) {
                    return "(No IP Addresses for this host)";
                }
                StringBuilder sb = new StringBuilder();
                for (IpAddress ip : ips) {
                    sb.append(ip.toString())
                            .append(COMMA);
                }
                removeTrailingComma(sb);
                return sb.toString();
            }

            private StringBuilder removeTrailingComma(StringBuilder sb) {
                int pos = sb.lastIndexOf(COMMA);
                sb.delete(pos, sb.length());
                return sb;
            }
        }
    }
}
