// Copyright 2012 Citrix Systems, Inc. Licensed under the
// Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License.  Citrix Systems, Inc.
// reserves all rights not expressly granted by 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.
// 
// Automatically generated by addcopyright.py at 04/03/2012
package com.xensource.xenapi;

import com.xensource.xenapi.Types.BadServerResponse;
import com.xensource.xenapi.Types.VersionException;
import com.xensource.xenapi.Types.XenAPIException;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.apache.xmlrpc.XmlRpcException;

/**
 * Data sources for logging in RRDs
 *
 * @author Citrix Systems, Inc.
 */
public class DataSource extends XenAPIObject {

    /**
     * The XenAPI reference to this object.
     */
    protected final String ref;

    /**
     * For internal use only.
     */
    DataSource(String ref) {
       this.ref = ref;
    }

    public String toWireString() {
       return this.ref;
    }

    /**
     * If obj is a DataSource, compares XenAPI references for equality.
     */
    @Override
    public boolean equals(Object obj)
    {
        if (obj != null && obj instanceof DataSource)
        {
            DataSource other = (DataSource) obj;
            return other.ref.equals(this.ref);
        } else
        {
            return false;
        }
    }

    @Override
    public int hashCode()
    {
        return ref.hashCode();
    }

    /**
     * Represents all the fields in a DataSource
     */
    public static class Record implements Types.Record {
        public String toString() {
            StringWriter writer = new StringWriter();
            PrintWriter print = new PrintWriter(writer);
            print.printf("%1$20s: %2$s\n", "nameLabel", this.nameLabel);
            print.printf("%1$20s: %2$s\n", "nameDescription", this.nameDescription);
            print.printf("%1$20s: %2$s\n", "enabled", this.enabled);
            print.printf("%1$20s: %2$s\n", "standard", this.standard);
            print.printf("%1$20s: %2$s\n", "units", this.units);
            print.printf("%1$20s: %2$s\n", "min", this.min);
            print.printf("%1$20s: %2$s\n", "max", this.max);
            print.printf("%1$20s: %2$s\n", "value", this.value);
            return writer.toString();
        }

        /**
         * Convert a data_source.Record to a Map
         */
        public Map<String,Object> toMap() {
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("name_label", this.nameLabel == null ? "" : this.nameLabel);
            map.put("name_description", this.nameDescription == null ? "" : this.nameDescription);
            map.put("enabled", this.enabled == null ? false : this.enabled);
            map.put("standard", this.standard == null ? false : this.standard);
            map.put("units", this.units == null ? "" : this.units);
            map.put("min", this.min == null ? 0.0 : this.min);
            map.put("max", this.max == null ? 0.0 : this.max);
            map.put("value", this.value == null ? 0.0 : this.value);
            return map;
        }

        /**
         * a human-readable name
         */
        public String nameLabel;
        /**
         * a notes field containg human-readable description
         */
        public String nameDescription;
        /**
         * true if the data source is being logged
         */
        public Boolean enabled;
        /**
         * true if the data source is enabled by default. Non-default data sources cannot be disabled
         */
        public Boolean standard;
        /**
         * the units of the value
         */
        public String units;
        /**
         * the minimum value of the data source
         */
        public Double min;
        /**
         * the maximum value of the data source
         */
        public Double max;
        /**
         * current value of the data source
         */
        public Double value;
    }

}