import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'
import { RobotArm, Pose, Joints, PoseInput, JointsInput } from './robotarm-type'
import { RobotArmAPI } from '../../controllers/robot-arm-api'

// extend type Mutation {
//   robotArmReset(name: String!): Boolean
//   robotArmGoHome(name: String!): Boolean
//   robotArmGoZero(name: String!): Boolean
//   robotArmTaskMoveTo(name: String!, pose: PoseInput!): Pose
//   robotArmTaskMoveBy(name: String!, pose: PoseInput!): Pose
//   robotArmTaskMoveByNoWait(name: String!, pose: PoseInput!): Pose
//   robotArmStartTeachingMode(name: String!): Boolean
//   robotArmFinishTeachingMode(name: String!): Boolean
//   robotArmJointMoveTo(name: String!, joints: JointsInput!): Joints
//   robotArmSetHome(name: String!, joints: JointsInput!): Joints
// }

@Resolver(RobotArm)
export class RobotArmMutation {
  @Mutation(returns => Boolean, { description: 'To run reset command of the robot' })
  async robotArmReset(
    @Arg('name', type => String, { nullable: false }) name: string,
    @Ctx() context: any
  ): Promise<boolean> {
    const { domain } = context.state

    return RobotArmAPI.reset(domain, name)
  }

  @Mutation(returns => Boolean, { description: 'To run goHome command of the robot' })
  async robotArmGoHome(
    @Arg('name', type => String, { nullable: false }) name: string,
    @Ctx() context: any
  ): Promise<boolean> {
    const { domain } = context.state

    return RobotArmAPI.goHome(domain, name)
  }

  @Mutation(returns => Boolean, { description: 'To run goZero command of the robot' })
  async robotArmGoZero(
    @Arg('name', type => String, { nullable: false }) name: string,
    @Ctx() context: any
  ): Promise<boolean> {
    const { domain } = context.state

    return RobotArmAPI.goZero(domain, name)
  }

  @Mutation(returns => Pose, { description: 'To run taskMoveTo command of the robot' })
  async robotArmTaskMoveTo(
    @Arg('name', type => String, { nullable: false }) name: string,
    @Arg('pose', type => PoseInput, { nullable: false }) pose: Pose,
    @Ctx() context: any
  ): Promise<Pose> {
    const { domain } = context.state

    return RobotArmAPI.moveTo(domain, name, { pose })
  }

  @Mutation(returns => Pose, { description: 'To run taskMoveBy command of the robot' })
  async robotArmTaskMoveBy(
    @Arg('name', type => String, { nullable: false }) name: string,
    @Arg('pose', type => PoseInput, { nullable: false }) pose: Pose,
    @Ctx() context: any
  ): Promise<Pose> {
    const { domain } = context.state

    return RobotArmAPI.moveBy(domain, name, { pose })
  }

  @Mutation(returns => Pose, { description: 'To run taskMoveBy command of the robot' })
  async robotArmTaskMoveByNoWait(
    @Arg('name', type => String, { nullable: false }) name: string,
    @Arg('pose', type => PoseInput, { nullable: false }) pose: Pose,
    @Ctx() context: any
  ): Promise<Pose> {
    const { domain } = context.state

    return RobotArmAPI.moveByNoWait(domain, name, { pose })
  }

  @Mutation(returns => Boolean, { description: 'To start teaching mode of the robot' })
  async robotArmStartTeachingMode(
    @Arg('name', type => String, { nullable: false }) name: string,
    @Ctx() context: any
  ): Promise<boolean> {
    const { domain } = context.state

    return RobotArmAPI.startTeachingMode(domain, name)
  }

  @Mutation(returns => Boolean, { description: 'To stop teaching mode of the robot' })
  async robotArmFinishTeachingMode(
    @Arg('name', type => String, { nullable: false }) name: string,
    @Ctx() context: any
  ): Promise<boolean> {
    const { domain } = context.state

    return RobotArmAPI.finishTeachingMode(domain, name)
  }

  @Mutation(returns => Joints, { description: 'To run jointMoveTo command of the robot' })
  async robotArmJointMoveTo(
    @Arg('name', type => String, { nullable: false }) name: string,
    @Arg('joints', type => JointsInput, { nullable: false }) joints: Joints,
    @Ctx() context: any
  ): Promise<Joints> {
    const { domain } = context.state

    return RobotArmAPI.moveToJoints(domain, name, { joints })
  }

  @Mutation(returns => Joints, { description: 'To set the home position of the robot' })
  async robotArmSetHome(
    @Arg('name', type => String, { nullable: false }) name: string,
    @Arg('joints', type => JointsInput, { nullable: false }) joints: Joints,
    @Ctx() context: any
  ): Promise<Joints> {
    const { domain } = context.state

    return RobotArmAPI.setHome(domain, name, { joints })
  }
}
