/*
 * Copyright 2014-present Open Networking Foundation
 *
 * 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.cli.net;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;

import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.apache.karaf.shell.api.action.Option;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.topology.Topology;
import org.onosproject.net.topology.TopologyProvider;
import org.onosproject.net.topology.TopologyService;

/**
 * Lists summary of the current topology.
 */
@Service
@Command(scope = "onos", name = "topology",
description = "Lists summary of the current topology")
public class TopologyCommand extends AbstractShellCommand {

    private static final String FMT = "created=%s, uptime=%s, devices=%d, links=%d, clusters=%d";

    @Option(name = "-r", aliases = "--recompute",
            description = "Trigger topology re-computation", required = false,
            multiValued = false)
    private boolean recompute = false;

    protected TopologyService service;
    protected Topology topology;

    /**
     * Initializes the context for all cluster commands.
     */
    protected void init() {
        service = get(TopologyService.class);
        topology = service.currentTopology();
    }

    @Override
    protected void doExecute() {
        init();
        long topologyUptime =
                Math.max(0, (System.currentTimeMillis() - topology.creationTime()));
        if (recompute) {
            get(TopologyProvider.class).triggerRecompute();

        } else if (outputJson()) {
            print("%s",
                    jsonForEntity(topology, Topology.class));
        } else {
            print(FMT, formatCreationTime(topology.creationTime()),
                    formatElapsedTime(topologyUptime),
                    topology.deviceCount(), topology.linkCount(),
                    topology.clusterCount());
        }
    }

    /**
     * Converts millis to a formatted elapsed time string.
     *
     * @param millis Duration in millis to convert to a string
     *
     * @return Formatted string: "D days, H hrs, M mins, S secs".
     */
    private static String formatElapsedTime(long millis) {
        if (millis < 0) {
            throw new IllegalArgumentException("Interval less than zero. "
                    + "Possible unsynchronized timestamps");
        }

        final long days = TimeUnit.MILLISECONDS.toDays(millis);
        millis -= TimeUnit.DAYS.toMillis(days);
        final long hours = TimeUnit.MILLISECONDS.toHours(millis);
        millis -= TimeUnit.HOURS.toMillis(hours);
        final long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
        millis -= TimeUnit.MINUTES.toMillis(minutes);
        final long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);

        final StringBuilder topologyUptimeString = new StringBuilder(64);
        topologyUptimeString.append(days);
        topologyUptimeString.append(" days, ");
        topologyUptimeString.append(hours);
        topologyUptimeString.append(" hrs, ");
        topologyUptimeString.append(minutes);
        topologyUptimeString.append(" mins, ");
        topologyUptimeString.append(seconds);
        topologyUptimeString.append(" secs");

        return (topologyUptimeString.toString());
    }

    /**
     * Converts millis to a formatted Date String.
     *
     * @param millis Duration in millis to convert to a string
     *
     * @return Formatted string: yyyy-MM-dd HH:mm:ss.
     */
    private static String formatCreationTime(long millis) {
        final DateFormat dateFormatter =
                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(millis);
        return (dateFormatter.format(calendar.getTime()));
    }
}
