/**
 * 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.oozie.sla;

import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

import org.apache.oozie.AppType;
import org.apache.oozie.client.OozieClient;
import org.apache.oozie.client.event.SLAEvent;
import org.apache.oozie.client.event.SLAEvent.EventStatus;
import org.apache.oozie.client.rest.JsonBean;
import org.apache.oozie.client.rest.JsonTags;
import org.apache.oozie.client.rest.JsonUtils;
import org.apache.oozie.util.DateUtils;
import org.apache.openjpa.persistence.jdbc.Index;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

@Entity
@Table(name = "SLA_SUMMARY")
@NamedQueries({

 @NamedQuery(name = "UPDATE_SLA_SUMMARY_FOR_SLA_STATUS", query = "update  SLASummaryBean w set w.slaStatus = :slaStatus,"
         + " w.eventStatus = :eventStatus, w.eventProcessed = :eventProcessed, w.lastModifiedTS = :lastModifiedTS "
         + "where w.jobId = :jobId"),

 @NamedQuery(name = "UPDATE_SLA_SUMMARY_FOR_STATUS_ACTUAL_TIMES", query = "update SLASummaryBean w set w.slaStatus = :slaStatus,"
         + " w.eventStatus = :eventStatus, w.eventProcessed = :eventProcessed, w.jobStatus = :jobStatus, w.lastModifiedTS "
         + "= :lastModifiedTS, w.actualStartTS = :actualStartTS, w.actualEndTS = :actualEndTS, w.actualDuration = :actualDuration"
         + " where w.jobId = :jobId"),

 @NamedQuery(name = "UPDATE_SLA_SUMMARY_FOR_EXPECTED_TIMES", query = "update SLASummaryBean w set w.nominalTimeTS "
         + "= :nominalTime, w.expectedStartTS = :expectedStartTime, w.expectedEndTS = :expectedEndTime, w.expectedDuration "
         + "= :expectedDuration , w.lastModifiedTS = :lastModTime where w.jobId = :jobId"),

 @NamedQuery(name = "UPDATE_SLA_SUMMARY_EVENTPROCESSED", query = "update SLASummaryBean w set w.eventProcessed "
         + "= :eventProcessed where w.jobId = :jobId"),

 @NamedQuery(name = "UPDATE_SLA_SUMMARY_LAST_MODIFIED_TIME", query = "update SLASummaryBean w set w.lastModifiedTS "
         + "= :lastModifiedTS where w.jobId = :jobId"),

 @NamedQuery(name = "UPDATE_SLA_SUMMARY_ALL", query = "update SLASummaryBean w set w.jobId = :jobId, w.appName = :appName,"
         + " w.appType = :appType, w.nominalTimeTS = :nominalTime, w.expectedStartTS = :expectedStartTime, w.expectedEndTS "
         + "= :expectedEndTime, w.expectedDuration = :expectedDuration, w.jobStatus = :jobStatus, w.slaStatus = :slaStatus,"
         + " w.eventStatus = :eventStatus, w.lastModifiedTS = :lastModTime, w.user = :user, w.parentId = :parentId,"
         + " w.eventProcessed = :eventProcessed, w.actualDuration = :actualDuration, w.actualEndTS = :actualEndTS,"
         + " w.actualStartTS = :actualStartTS where w.jobId = :jobId"),

 @NamedQuery(name = "GET_SLA_SUMMARY", query = "select OBJECT(w) from SLASummaryBean w where w.jobId = :id"),

 @NamedQuery(name = "GET_SLA_SUMMARY_RECORDS_RESTART", query = "select OBJECT(w) from SLASummaryBean w where w.eventProcessed "
         + "<= 7 AND w.lastModifiedTS >= :lastModifiedTime"),

 @NamedQuery(name = "GET_SLA_SUMMARY_EVENTPROCESSED", query = "select w.eventProcessed from SLASummaryBean w where w.jobId = :id"),

 @NamedQuery(name = "GET_SLA_SUMMARY_EVENTPROCESSED_LAST_MODIFIED",
         query = "select w.eventProcessed, w.lastModifiedTS from SLASummaryBean w where w.jobId = :id"),

 @NamedQuery(name = "GET_SLA_SUMMARY_ALL", query = "select OBJECT(w) from SLASummaryBean w")

})

/**
 * Class to store all the SLA related details (summary) per job
 */
public class SLASummaryBean implements JsonBean {

    @Id
    @Basic
    @Column(name = "job_id")
    private String jobId;

    @Basic
    @Index
    @Column(name = "parent_id")
    private String parentId;

    @Basic
    @Index
    @Column(name = "app_name")
    private String appName;

    @Basic
    @Column(name = "app_type")
    private String appType;

    @Basic
    @Column(name = "user_name")
    private String user;

    @Basic
    @Column(name = "created_time")
    private Timestamp createdTimeTS = null;

    @Basic
    @Index
    @Column(name = "nominal_time")
    private Timestamp nominalTimeTS = null;

    @Basic
    @Column(name = "expected_start")
    private Timestamp expectedStartTS = null;

    @Basic
    @Column(name = "expected_end")
    private Timestamp expectedEndTS = null;

    @Basic
    @Column(name = "expected_duration")
    private long expectedDuration = -1;

    @Basic
    @Column(name = "actual_start")
    private Timestamp actualStartTS = null;

    @Basic
    @Column(name = "actual_end")
    private Timestamp actualEndTS = null;

    @Basic
    @Column(name = "actual_duration")
    private long actualDuration = -1;

    @Basic
    @Column(name = "job_status")
    private String jobStatus;

    @Basic
    @Column(name = "event_status")
    private String eventStatus;

    @Basic
    @Column(name = "sla_status")
    private String slaStatus;

    @Basic
    @Index
    @Column(name = "event_processed")
    private byte eventProcessed = 0;

    @Basic
    @Index
    @Column(name = "last_modified")
    private Timestamp lastModifiedTS = null;

    public SLASummaryBean() {
    }

    public SLASummaryBean(SLACalcStatus slaCalc) {
        SLARegistrationBean reg = slaCalc.getSLARegistrationBean();
        setId(slaCalc.getId());
        setAppName(reg.getAppName());
        setAppType(reg.getAppType());
        setNominalTime(reg.getNominalTime());
        setExpectedStart(reg.getExpectedStart());
        setExpectedEnd(reg.getExpectedEnd());
        setExpectedDuration(reg.getExpectedDuration());
        setJobStatus(slaCalc.getJobStatus());
        setSLAStatus(slaCalc.getSLAStatus());
        setEventStatus(slaCalc.getEventStatus());
        setLastModifiedTime(slaCalc.getLastModifiedTime());
        setUser(reg.getUser());
        setParentId(reg.getParentId());
        setEventProcessed(slaCalc.getEventProcessed());
        setActualDuration(slaCalc.getActualDuration());
        setActualEnd(slaCalc.getActualEnd());
        setActualStart(slaCalc.getActualStart());
    }

    public String getId() {
        return jobId;
    }

    public void setId(String jobId) {
        this.jobId = jobId;
    }

    public String getParentId() {
        return parentId;
    }

    public void setParentId(String parentId) {
        this.parentId = parentId;
    }

    public Timestamp getCreatedTimestamp() {
        return createdTimeTS;
    }

    public void setCreatedTimestamp(Timestamp createdTime) {
        this.createdTimeTS = createdTime;
    }

    public Date getCreatedTime() {
        return DateUtils.toDate(createdTimeTS);
    }

    public void setCreatedTime(Date createdTime) {
        this.createdTimeTS = DateUtils.convertDateToTimestamp(createdTime);
    }

    public Date getNominalTime() {
        return DateUtils.toDate(nominalTimeTS);
    }

    public Timestamp getNominalTimestamp() {
        return this.nominalTimeTS;
    }

    public void setNominalTime(Date nominalTime) {
        this.nominalTimeTS = DateUtils.convertDateToTimestamp(nominalTime);
    }


    public Date getExpectedStart() {
        return DateUtils.toDate(expectedStartTS);
    }

    public Timestamp getExpectedStartTimestamp() {
        return this.expectedStartTS;
    }

    public void setExpectedStart(Date expectedStart) {
        this.expectedStartTS = DateUtils.convertDateToTimestamp(expectedStart);
    }

    public Date getExpectedEnd() {
        return DateUtils.toDate(expectedEndTS);
    }

    public Timestamp getExpectedEndTimestamp() {
        return this.expectedEndTS;
    }
    public void setExpectedEnd(Date expectedEnd) {
        this.expectedEndTS = DateUtils.convertDateToTimestamp(expectedEnd);
    }

    public long getExpectedDuration() {
        return expectedDuration;
    }

    public void setExpectedDuration(long expectedDuration) {
        this.expectedDuration = expectedDuration;
    }

    public Date getActualStart() {
        return DateUtils.toDate(actualStartTS);
    }

    public Timestamp getActualStartTimestamp() {
        return this.actualStartTS;
    }

    public void setActualStart(Date actualStart) {
        this.actualStartTS = DateUtils.convertDateToTimestamp(actualStart);
    }

    public Date getActualEnd() {
        return DateUtils.toDate(actualEndTS);
    }

    public Timestamp getActualEndTimestamp() {
        return this.actualEndTS;
    }

    public void setActualEnd(Date actualEnd) {
        this.actualEndTS = DateUtils.convertDateToTimestamp(actualEnd);
    }

    public long getActualDuration() {
        return actualDuration;
    }

    public void setActualDuration(long actualDuration) {
        this.actualDuration = actualDuration;
    }

    public String getJobStatus() {
        return jobStatus;
    }

    public void setJobStatus(String status) {
        this.jobStatus = status;
    }

    public SLAEvent.EventStatus getEventStatus() {
        return (eventStatus != null ? SLAEvent.EventStatus.valueOf(eventStatus) : null);
    }

    public void setEventStatus(SLAEvent.EventStatus eventStatus) {
        this.eventStatus = (eventStatus != null ? eventStatus.name() : null);
    }

    public SLAEvent.SLAStatus getSLAStatus() {
        return (slaStatus != null ? SLAEvent.SLAStatus.valueOf(slaStatus) : null);
    }

    public String getSLAStatusString() {
        return slaStatus;
    }

    public String getEventStatusString() {
        return eventStatus;
    }

    public void setSLAStatus(SLAEvent.SLAStatus stage) {
        this.slaStatus = (stage != null ? stage.name() : null);
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getAppName() {
        return appName;
    }

    public void setAppName(String appName) {
        this.appName = appName;
    }

    public AppType getAppType() {
        return AppType.valueOf(appType);
    }

    public void setAppType(AppType appType) {
        this.appType = appType.toString();
    }

    public byte getEventProcessed() {
        return eventProcessed;
    }

    public void setEventProcessed(int eventProcessed) {
        this.eventProcessed = (byte)eventProcessed;
    }

    public Date getLastModifiedTime() {
        return DateUtils.toDate(lastModifiedTS);
    }

    public Timestamp getLastModifiedTimestamp() {
        return this.lastModifiedTS;
    }

    public void setLastModifiedTime(Date lastModified) {
        this.lastModifiedTS = DateUtils.convertDateToTimestamp(lastModified);
    }

    @Override
    public JSONObject toJSONObject() {
        return toJSONObject(null);
    }

    @Override
    @SuppressWarnings("unchecked")
    public JSONObject toJSONObject(String timeZoneId) {
        JSONObject json = new JSONObject();
        Map<EventStatus,Long> eventMap = calculateEventStatus();
        StringBuilder eventStatusStr = new StringBuilder();
        boolean first = true;
        for(EventStatus e: eventMap.keySet()) {
            if(!first) {
                eventStatusStr.append(",");
            }
            eventStatusStr.append(e.toString());
            first = false;
        }
        json.put(JsonTags.SLA_SUMMARY_ID, jobId);
        if (parentId != null) {
            json.put(JsonTags.SLA_SUMMARY_PARENT_ID, parentId);
        }
        json.put(JsonTags.SLA_SUMMARY_APP_NAME, appName);
        json.put(JsonTags.SLA_SUMMARY_APP_TYPE, appType);
        json.put(JsonTags.SLA_SUMMARY_USER, user);
        json.put(JsonTags.SLA_SUMMARY_NOMINAL_TIME, getTimeOnTimeZone(nominalTimeTS, timeZoneId));
        if (expectedStartTS != null) {
            json.put(JsonTags.SLA_SUMMARY_EXPECTED_START, getTimeOnTimeZone(expectedStartTS, timeZoneId));
        } else {
            json.put(JsonTags.SLA_SUMMARY_EXPECTED_START, null);
        }

        if (actualStartTS != null) {
            json.put(JsonTags.SLA_SUMMARY_ACTUAL_START, getTimeOnTimeZone(actualStartTS, timeZoneId));
        }
        else {
            json.put(JsonTags.SLA_SUMMARY_ACTUAL_START, null);
        }
        Long startDelay = eventMap.get(EventStatus.START_MET) != null ? eventMap.get(EventStatus.START_MET) : eventMap
                .get(EventStatus.START_MISS);
        if (startDelay != null) {
            json.put(JsonTags.SLA_SUMMARY_START_DELAY, startDelay);
        }
        if (expectedEndTS != null ) {
            json.put(JsonTags.SLA_SUMMARY_EXPECTED_END, getTimeOnTimeZone(expectedEndTS,timeZoneId));
        } else {
            json.put(JsonTags.SLA_SUMMARY_ACTUAL_END, null);
        }
        if (actualEndTS != null) {
            json.put(JsonTags.SLA_SUMMARY_ACTUAL_END, getTimeOnTimeZone(actualEndTS,timeZoneId));
        }
        else {
            json.put(JsonTags.SLA_SUMMARY_ACTUAL_END, null);
        }
        Long endDelay = eventMap.get(EventStatus.END_MET) != null ? eventMap.get(EventStatus.END_MET) : eventMap
                .get(EventStatus.END_MISS);
        if (endDelay != null) {
            json.put(JsonTags.SLA_SUMMARY_END_DELAY, endDelay);
        }
        json.put(JsonTags.SLA_SUMMARY_EXPECTED_DURATION, expectedDuration);
        if (actualDuration == -1 && expectedDuration != -1 && actualStartTS != null) {
            long currentDur = new Date().getTime() - actualStartTS.getTime();
            json.put(JsonTags.SLA_SUMMARY_ACTUAL_DURATION, currentDur);
        }
        else {
            json.put(JsonTags.SLA_SUMMARY_ACTUAL_DURATION, actualDuration);
        }
        Long durationDelay = eventMap.get(EventStatus.DURATION_MET) != null ? eventMap.get(EventStatus.DURATION_MET)
                : eventMap.get(EventStatus.DURATION_MISS);
        if (durationDelay != null) {
            json.put(JsonTags.SLA_SUMMARY_DURATION_DELAY, durationDelay / (1000 * 60));
        }
        json.put(JsonTags.SLA_SUMMARY_JOB_STATUS, jobStatus);
        json.put(JsonTags.SLA_SUMMARY_SLA_STATUS, slaStatus);
        json.put(JsonTags.SLA_SUMMARY_EVENT_STATUS, eventStatusStr.toString());
        json.put(JsonTags.SLA_SUMMARY_LAST_MODIFIED, getTimeOnTimeZone(lastModifiedTS, timeZoneId));
        return json;
    }

    private Object getTimeOnTimeZone(Timestamp ts, String timeZoneId) {
        Object ret = null;
        if(timeZoneId == null) {
            ret = new Long(String.valueOf(ts.getTime()));
        } else {
            ret = JsonUtils.formatDateRfc822(ts, timeZoneId);
        }
        return ret;
    }

    private Map<EventStatus, Long> calculateEventStatus() {
        Map<EventStatus, Long> events = new HashMap<EventStatus, Long>();
        if (expectedStartTS != null) {
            if (actualStartTS != null) {
                long diff = (actualStartTS.getTime() - expectedStartTS.getTime()) / (1000 * 60);
                if (diff > 0) {
                    events.put(EventStatus.START_MISS, diff);
                }
                else {
                    events.put(EventStatus.START_MET, diff);
                }
            }
            else {
                long diff = (new Date().getTime() - expectedStartTS.getTime()) / (1000 * 60);
                if (diff > 0) {
                    events.put(EventStatus.START_MISS, diff);
                }
            }
        }
        if (expectedDuration != -1) {
            if (actualDuration != -1) {
                long diff = actualDuration - expectedDuration;
                if (diff > 0) {
                    events.put(EventStatus.DURATION_MISS, diff);
                }
                else {
                    events.put(EventStatus.DURATION_MET, diff);
                }
            }
            else {
                if (actualStartTS != null) {
                    long currentDur = new Date().getTime() - actualStartTS.getTime();
                    if (expectedDuration < currentDur) {
                        events.put(EventStatus.DURATION_MISS, currentDur - expectedDuration);
                    }
                }
            }
        }
        if (expectedEndTS != null) {
            if (actualEndTS != null) {
                long diff = (actualEndTS.getTime() - expectedEndTS.getTime()) / (1000 * 60);
                if (diff > 0) {
                    events.put(EventStatus.END_MISS, diff);
                }
                else {
                    events.put(EventStatus.END_MET, diff);
                }
            }
            else {
                long diff = (new Date().getTime() - expectedEndTS.getTime()) / (1000 * 60);
                if (diff > 0) {
                    events.put(EventStatus.END_MISS, diff);
                }
            }
        }
        return events;
    }
    /**
     * Convert a sla summary list into a json object.
     *
     * @param slaSummaryList sla summary list.
     * @param timeZoneId time zone to use for dates in the JSON array.
     * @return the corresponding JSON object.
     */
    @SuppressWarnings("unchecked")
    public static JSONObject toJSONObject(List<? extends SLASummaryBean> slaSummaryList, String timeZoneId) {
        JSONObject json = new JSONObject();
        JSONArray array = new JSONArray();
        if (slaSummaryList != null) {
            for (SLASummaryBean summary : slaSummaryList) {
                array.add(summary.toJSONObject(timeZoneId));
            }
        }
        json.put(JsonTags.SLA_SUMMARY_LIST, array);
        return json;
    }

    @SuppressWarnings("unchecked")
    public static JSONObject toJSONObject(List<? extends SLASummaryBean> slaSummaryList,
            Map<String, Map<String, String>> slaConfigMap, String timeZoneId) {
        JSONObject json = new JSONObject();
        JSONArray array = new JSONArray();
        if (slaSummaryList != null) {
            for (SLASummaryBean summary : slaSummaryList) {
                JSONObject slaJson = summary.toJSONObject(timeZoneId);
                String slaAlertStatus = "";
                if (slaConfigMap.containsKey(summary.getId())) {
                    slaAlertStatus = slaConfigMap.get(summary.getId()).containsKey(OozieClient.SLA_DISABLE_ALERT) ? "Disabled"
                            : "Enabled";
                }
                slaJson.put(JsonTags.SLA_ALERT_STATUS, slaAlertStatus);
                array.add(slaJson);
            }
        }
        json.put(JsonTags.SLA_SUMMARY_LIST, array);
        return json;
    }
}
