/*
 * 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.faultmanagement.web;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.IOException;
import java.io.InputStream;
import org.onosproject.rest.AbstractWebResource;

import javax.ws.rs.core.Response;
import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId;

import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.apache.commons.lang.StringUtils;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmService;
import org.onosproject.net.DeviceId;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Alarms on devices or ONOS.
 */
@Path("alarms")
public class AlarmsWebResource extends AbstractWebResource {

    public static final String ALARM_NOT_FOUND = "Alarm is not found";

    private final Logger log = getLogger(getClass());

    /**
     * Get alarms. Returns a list of alarms
     *
     * @param includeCleared (optional) include recently cleared alarms in response
     * @param devId (optional) include only for specified device
     * @return JSON encoded set of alarms
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getAlarms(@DefaultValue("false") @QueryParam("includeCleared") boolean includeCleared,
            @DefaultValue("") @QueryParam("devId") String devId
    ) {

        log.info("Requesting all alarms, includeCleared={}", includeCleared);
        AlarmService service = get(AlarmService.class);

        Iterable<Alarm> alarms;
        if (StringUtils.isBlank(devId)) {
            alarms = includeCleared
                    ? service.getAlarms()
                    : service.getActiveAlarms();
        } else {
            alarms = service.getAlarms(DeviceId.deviceId(devId));
        }
        ObjectNode result = new ObjectMapper().createObjectNode();
        result.set("alarms", new AlarmCodec().encode(alarms, this));
        return ok(result.toString()).build();

    }

    /**
     * Get specified alarm. Returns details of the specified alarm.
     *
     * @param id ONOS allocated identifier
     * @return JSON encoded alarm
     */
    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getAlarm(@PathParam("id") String id) {
        log.info("HTTP GET alarm for id={}", id);

        AlarmId alarmId = toAlarmId(id);
        Alarm alarm = get(AlarmService.class).getAlarm(alarmId);

        ObjectNode result = new ObjectMapper().createObjectNode();
        result.set("alarm", new AlarmCodec().encode(alarm, this));
        return ok(result.toString()).build();
    }

    /**
     * Update book-keeping fields on the alarm. Returns an up-to-date version of the alarm. Some of its fields may have
     * been updated since the REST client last retrieved the alarm being updated.
     *
     * @param alarmIdPath alarm id path
     * @param stream input JSON
     * @return updated JSON encoded alarm
     */
    @PUT
    @Path("{alarm_id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response update(@PathParam("alarm_id") String alarmIdPath, InputStream stream) {
        log.info("PUT NEW ALARM at /{}", alarmIdPath);

        try {
            ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
            log.info("jsonTree={}", jsonTree);

            Alarm alarm = new AlarmCodec().decode(jsonTree, this);

            AlarmService service = get(AlarmService.class);

            if (Long.parseLong(alarmIdPath) != alarm.id().fingerprint()) {
                throw new IllegalArgumentException("id in path is " + Long.parseLong(alarmIdPath)
                        + " but payload uses id=" + alarm.id().fingerprint());

            }
            Alarm updated = service.updateBookkeepingFields(
                    alarm.id(), alarm.acknowledged(), alarm.assignedUser()
            );
            ObjectNode encoded = new AlarmCodec().encode(updated, this);
            return ok(encoded.toString()).build();

        } catch (IOException ioe) {
            throw new IllegalArgumentException(ioe);
        }
    }

    private static AlarmId toAlarmId(String id) {
        try {
            return AlarmId.alarmId(Long.parseLong(id));
        } catch (NumberFormatException ex) {
            throw new IllegalArgumentException("Alarm id should be numeric", ex);
        }

    }

}
