/*
 * 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 "common.thrift"
namespace java org.apache.iotdb.mlnode.rpc.thrift
namespace py iotdb.thrift.mlnode

struct TCreateTrainingTaskReq {
  1: required string modelId
  2: required map<string, string> options
  3: required map<string, string> hyperparameters
  4: required string datasetFetchSQL
}

struct TDeleteModelReq {
  1: required string modelId
  2: optional string trialId
}

struct TForecastReq {
  1: required string modelPath
  2: required binary inputData
  3: required list<string> inputTypeList
  4: required list<string> inputColumnNameList
  5: required i32 predictLength
}

struct TForecastResp {
  1: required common.TSStatus status
  2: required binary forecastResult
}

service IMLNodeRPCService {

  // -------------- For Config Node --------------

  common.TSStatus createTrainingTask(TCreateTrainingTaskReq req)

  common.TSStatus deleteModel(TDeleteModelReq req)

  // -------------- For Data Node --------------

  TForecastResp forecast(TForecastReq req)
}