/*
 * Licensed to Elasticsearch under one or more contributor
 * license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright
 * ownership. Elasticsearch 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.elasticsearch.index.rankeval;

import org.elasticsearch.action.support.ToXContentToBytes;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;

import java.io.IOException;
import java.util.Objects;

public class RatedDocumentKey extends ToXContentToBytes implements Writeable {
    public static final ParseField DOC_ID_FIELD = new ParseField("doc_id");
    public static final ParseField TYPE_FIELD = new ParseField("type");
    public static final ParseField INDEX_FIELD = new ParseField("index");

    private static final ObjectParser<RatedDocumentKey, RankEvalContext> PARSER = new ObjectParser<>("ratings", RatedDocumentKey::new);

    static {
        PARSER.declareString(RatedDocumentKey::setIndex, INDEX_FIELD);
        PARSER.declareString(RatedDocumentKey::setType, TYPE_FIELD);
        PARSER.declareString(RatedDocumentKey::setDocId, DOC_ID_FIELD);
    }
    
    @Override
    public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
        builder.startObject();
        builder.field(INDEX_FIELD.getPreferredName(), index);
        builder.field(TYPE_FIELD.getPreferredName(), type);
        builder.field(DOC_ID_FIELD.getPreferredName(), docId);
        builder.endObject();
        return builder;
    }
    
    // TODO instead of docId use path to id and id itself
    private String docId;
    private String type;
    private String index;

    public RatedDocumentKey() {}
    

    void setIndex(String index) {
        this.index = index;
    }

    void setType(String type) {
        this.type = type;
    }
    
    void setDocId(String docId) {
        this.docId = docId;
    }

    public RatedDocumentKey(String index, String type, String docId) {
        this.index = index;
        this.type = type;
        this.docId = docId;
    }

    public RatedDocumentKey(StreamInput in) throws IOException {
        this.index = in.readString();
        this.type = in.readString();
        this.docId = in.readString();
    }

    public String getIndex() {
        return index;
    }

    public String getType() {
        return type;
    }

    public String getDocID() {
        return docId;
    }

    @Override
    public void writeTo(StreamOutput out) throws IOException {
        out.writeString(index);
        out.writeString(type);
        out.writeString(docId);
    }
    
    public static RatedDocumentKey fromXContent(XContentParser parser, RankEvalContext context) throws IOException {
        return PARSER.parse(parser, context);
    }

    @Override
    public final boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        RatedDocumentKey other = (RatedDocumentKey) obj;
        return Objects.equals(index, other.index) &&
                Objects.equals(type, other.type) &&
                Objects.equals(docId, other.docId);
    }
    
    @Override
    public final int hashCode() {
        return Objects.hash(getClass(), index, type, docId);
    }
}

@@ -1134,16 +1134,28 @@
 content.
+Constructing
 ObjectPa
@@ -1658,16 +1658,28 @@
 c final 
+Constructing
 ObjectPa
@@ -1731,16 +1731,28 @@
 R = new 
+Constructing
 ObjectPa
@@ -1772,30 +1772,91 @@
 gs%22,
- RatedDocumentKey::new
+%0A            a -%3E new RatedDocumentKey((String) a%5B0%5D, (String) a%5B1%5D, (String) a%5B2%5D)
 );%0A%0A
@@ -1901,34 +1901,49 @@
 ing(
-RatedDocumentKey::setIndex
+ConstructingObjectParser.constructorArg()
 , IN
@@ -1987,33 +1987,49 @@
 ing(
-RatedDocumentKey::setType
+ConstructingObjectParser.constructorArg()
 , TY
@@ -2072,34 +2072,49 @@
 ing(
-RatedDocumentKey::setDocId
+ConstructingObjectParser.constructorArg()
 , DO
@@ -2124,36 +2124,32 @@
 D_FIELD);%0A    %7D%0A
-    
 %0A    @Override%0A 
@@ -2517,28 +2517,24 @@
 lder;%0A    %7D%0A
-    
 %0A    // TODO
@@ -2662,47 +2662,8 @@
 x;%0A%0A
-    public RatedDocumentKey() %7B%7D%0A    %0A%0A
     
@@ -3710,21 +3710,21 @@
  PARSER.
-parse
+apply
 (parser,

Add ConstructingObjectParser to RatedDocumentKey