content: /*
   * 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.ambari.server.state.theme;
  
  import java.util.ArrayList;
  import java.util.LinkedHashMap;
  import java.util.List;
  import java.util.Map;
  
  import org.apache.ambari.server.controller.ApiModel;
  
  import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
  import com.fasterxml.jackson.annotation.JsonInclude;
  import com.fasterxml.jackson.annotation.JsonProperty;
  
  import io.swagger.annotations.ApiModelProperty;
  
  @JsonInclude(JsonInclude.Include.NON_NULL)
  @JsonIgnoreProperties(ignoreUnknown = true)
  public class ThemeConfiguration implements ApiModel {
  	@JsonProperty("placement")
  	private Placement placement;
  
  	@JsonProperty("widgets")
  	private List<WidgetEntry> widgets;
  
  	@JsonProperty("layouts")
  	private List<Layout> layouts;
  
    @ApiModelProperty(name = "placement")
    public Placement getPlacement() {
      return placement;
    }
  
    public void setPlacement(Placement placement) {
      this.placement = placement;
    }
  
    @ApiModelProperty(name = "widgets")
    public List<WidgetEntry> getWidgets() {
      return widgets;
    }
  
    public void setWidgets(List<WidgetEntry> widgets) {
      this.widgets = widgets;
    }
  
    @ApiModelProperty(name = "layouts")
    public List<Layout> getLayouts() {
      return layouts;
    }
  
    public void setLayouts(List<Layout> layouts) {
      this.layouts = layouts;
    }
  
    public void mergeWithParent(ThemeConfiguration parent) {
      if (parent == null) {
        return;
      }
  
      if (placement == null) {
        placement = parent.placement;
      } else {
        placement.mergeWithParent(parent.placement);
      }
  
      if (widgets == null) {
        widgets = parent.widgets;
      } else if (parent.widgets != null) {
        widgets = mergeWidgets(parent.widgets, widgets);
      }
  
      if (layouts == null) {
        layouts = parent.layouts;
      } else if (parent.layouts != null) {
        layouts = mergeLayouts(parent.layouts, layouts);
      }
  
  
    }
  
    private List<Layout> mergeLayouts(List<Layout> parentLayouts, List<Layout> childLayouts) {
      Map<String, Layout> mergedLayouts = new LinkedHashMap<>();
  
      for (Layout parentLayout : parentLayouts) {
        mergedLayouts.put(parentLayout.getName(), parentLayout);
      }
  
      for (Layout childLayout : childLayouts) {
        if (childLayout.getName() != null) { //skip invalid entries
          if (childLayout.getTabs() == null) {
            mergedLayouts.remove(childLayout.getName());
          } else {
            Layout parentLayout = mergedLayouts.get(childLayout.getName());
            childLayout.mergeWithParent(parentLayout);
            mergedLayouts.put(childLayout.getName(), childLayout);
          }
        }
      }
  
      return new ArrayList<>(mergedLayouts.values());
  
    }
  
    private List<WidgetEntry> mergeWidgets(List<WidgetEntry> parentWidgets, List<WidgetEntry> childWidgets) {
      Map<String, WidgetEntry> mergedWidgets = new LinkedHashMap<>();
      for (WidgetEntry widgetEntry : parentWidgets) {
        mergedWidgets.put(widgetEntry.getConfig(), widgetEntry);
      }
  
      for (WidgetEntry widgetEntry : childWidgets) {
        if (widgetEntry.getConfig() != null) { //skip invalid entries
          if (widgetEntry.getWidget() == null) {
            mergedWidgets.remove(widgetEntry.getConfig());
          } else {
            mergedWidgets.put(widgetEntry.getConfig(), widgetEntry);
          }
        }
  
      }
  
      return new ArrayList<>(mergedWidgets.values());
    }
  }
  