/*
 * 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.
 */

#include "GetContainerStatusesRequest.h"

namespace libyarn {

GetContainerStatusesRequest::GetContainerStatusesRequest() {
	requestProto = GetContainerStatusesRequestProto::default_instance();
}

GetContainerStatusesRequest::GetContainerStatusesRequest(
		const GetContainerStatusesRequestProto &proto) :
		requestProto(proto) {
}

GetContainerStatusesRequest::~GetContainerStatusesRequest() {
}

GetContainerStatusesRequestProto& GetContainerStatusesRequest::getProto() {
	return requestProto;
}

list<ContainerId> GetContainerStatusesRequest::getContainerIds() {
	list<ContainerId> idList;
	for (int i = 0; i < requestProto.container_id_size(); i++) {
		idList.push_back(ContainerId(requestProto.container_id(i)));
	}
	return idList;
}

void GetContainerStatusesRequest::setContainerIds(
		list<ContainerId> &containerIds) {
	list<ContainerId>::iterator it = containerIds.begin();
	for (; it != containerIds.end(); it++) {
		ContainerIdProto* idProto = requestProto.add_container_id();
		idProto->CopyFrom((*it).getProto());
	}
}

} /* namespace libyarn */
