/*
 * Copyright 2015 Red Hat, Inc. and/or its affiliates
 * and other contributors as indicated by the @author tags.
 *
 * 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.hawkular.inventory.bus.api;

import com.google.gson.annotations.Expose;
import org.hawkular.bus.common.BasicMessage;
import org.hawkular.inventory.api.Action;
import org.hawkular.inventory.api.model.Environment;
import org.hawkular.inventory.api.model.Feed;
import org.hawkular.inventory.api.model.Metric;
import org.hawkular.inventory.api.model.MetricType;
import org.hawkular.inventory.api.model.Relationship;
import org.hawkular.inventory.api.model.Resource;
import org.hawkular.inventory.api.model.ResourceType;
import org.hawkular.inventory.api.model.Tenant;

/**
 * @author Lukas Krejci
 * @since 0.0.1
 */
public abstract class InventoryEvent<T> extends BasicMessage {
    @Expose
    private Action.Enumerated action;

    @SuppressWarnings("unchecked")
    public static <O> InventoryEvent<O> from(Action<?, ?> action, O object) {
        if (object == null) {
            throw new IllegalArgumentException("object == null");
        }

        if (action == null) {
            throw new IllegalArgumentException("action == null");
        }

        if (object instanceof Tenant) {
            return (InventoryEvent<O>) new TenantEvent(action.asEnum(), (Tenant) object);
        } else if (object instanceof Environment) {
            return (InventoryEvent<O>) new EnvironmentEvent(action.asEnum(), (Environment) object);
        } else if (object instanceof Feed) {
            return (InventoryEvent<O>) new FeedEvent(action.asEnum(), (Feed) object);
        } else if (object instanceof Metric) {
            return (InventoryEvent<O>) new MetricEvent(action.asEnum(), (Metric) object);
        } else if (object instanceof MetricType) {
            return (InventoryEvent<O>) new MetricTypeEvent(action.asEnum(), (MetricType) object);
        } else if (object instanceof Resource) {
            return (InventoryEvent<O>) new ResourceEvent(action.asEnum(), (Resource) object);
        } else if (object instanceof ResourceType) {
            return (InventoryEvent<O>) new ResourceTypeEvent(action.asEnum(), (ResourceType) object);
        } else if (object instanceof Relationship) {
            return (InventoryEvent<O>) new RelationshipEvent(action.asEnum(), (Relationship) object);
        } else {
            throw new IllegalArgumentException("Unsupported entity type: " + object.getClass());
        }
    }

    protected InventoryEvent() {

    }

    protected InventoryEvent(Action.Enumerated action) {
        this.action = action;
    }

    public Action.Enumerated getAction() {
        return action;
    }

    public void setAction(Action.Enumerated action) {
        this.action = action;
    }

    public abstract T getObject();

    public abstract void setObject(T object);
}

@@ -842,16 +842,73 @@
 Action;%0A
+import org.hawkular.inventory.api.model.AbstractElement;%0A
 import o
@@ -1471,43 +1471,8 @@
 n;%0A%0A
-    @SuppressWarnings(%22unchecked%22)%0A
     
@@ -1488,12 +1488,8 @@
 atic
- %3CO%3E
  Inv
@@ -1500,17 +1500,17 @@
 ryEvent%3C
-O
+?
 %3E from(A
@@ -1530,16 +1530,21 @@
 ction, O
+bject
  object)
@@ -1818,36 +1818,16 @@
   return
- (InventoryEvent%3CO%3E)
  new Ten
@@ -1940,36 +1940,16 @@
   return
- (InventoryEvent%3CO%3E)
  new Env
@@ -2065,36 +2065,16 @@
   return
- (InventoryEvent%3CO%3E)
  new Fee
@@ -2178,36 +2178,16 @@
   return
- (InventoryEvent%3CO%3E)
  new Met
@@ -2299,36 +2299,16 @@
   return
- (InventoryEvent%3CO%3E)
  new Met
@@ -2426,36 +2426,16 @@
   return
- (InventoryEvent%3CO%3E)
  new Res
@@ -2553,36 +2553,16 @@
   return
- (InventoryEvent%3CO%3E)
  new Res
@@ -2693,28 +2693,8 @@
 urn 
-(InventoryEvent%3CO%3E) 
 new 
@@ -2741,32 +2741,567 @@
 tionship) object
+);%0A        %7D else if (object instanceof Action.Update) %7B%0A            @SuppressWarnings(%22unchecked%22)%0A            AbstractElement%3C?, AbstractElement.Update%3E updated =%0A                    (AbstractElement%3C?, AbstractElement.Update%3E) ((Action.Update) object).getOriginalEntity();%0A%0A            updated.update().with((AbstractElement.Update) ((Action.Update) object).getUpdate());%0A%0A            //TODO should we instead send the whole update object? No time for that now, but it'd be preferable I think%0A            return from(action, updated
 );%0A        %7D els

Fix publishing entity updates to the bus.