# frozen_string_literal: true

# Copyright 2018 IBM All Rights Reserved.
#
# Licensed 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.

# The IBM Watson™ Visual Recognition service uses deep learning algorithms to
# identify scenes, objects, and faces  in images you upload to the service. You can create
# and train a custom classifier to identify subjects that suit your needs.

require "concurrent"
require "erb"
require "json"
require "ibm_cloud_sdk_core"
require_relative "./common.rb"

# Module for the Watson APIs
module IBMWatson
  ##
  # The Visual Recognition V3 service.
  class VisualRecognitionV3 < IBMCloudSdkCore::BaseService
    include Concurrent::Async
    ##
    # @!method initialize(args)
    # Construct a new client for the Visual Recognition service.
    #
    # @param args [Hash] The args to initialize with
    # @option args version [String] The API version date to use with the service, in
    #   "YYYY-MM-DD" format. Whenever the API is changed in a backwards
    #   incompatible way, a new minor version of the API is released.
    #   The service uses the API version for the date you specify, or
    #   the most recent version before that date. Note that you should
    #   not programmatically specify the current date at runtime, in
    #   case the API has been updated since your application's release.
    #   Instead, specify a version date that is compatible with your
    #   application, and don't change it until your application is
    #   ready for a later version.
    # @option args url [String] The base url to use when contacting the service (e.g.
    #   "https://gateway.watsonplatform.net/visual-recognition/api").
    #   The base url may differ between Bluemix regions.
    # @option args iam_apikey [String] An API key that can be used to request IAM tokens. If
    #   this API key is provided, the SDK will manage the token and handle the
    #   refreshing.
    # @option args iam_access_token [String] An IAM access token is fully managed by the application.
    #   Responsibility falls on the application to refresh the token, either before
    #   it expires or reactively upon receiving a 401 from the service as any requests
    #   made with an expired token will fail.
    # @option args iam_url [String] An optional URL for the IAM service API. Defaults to
    #   'https://iam.ng.bluemix.net/identity/token'.
    def initialize(args = {})
      @__async_initialized__ = false
      defaults = {}
      defaults[:version] = nil
      defaults[:url] = "https://gateway.watsonplatform.net/visual-recognition/api"
      defaults[:iam_apikey] = nil
      defaults[:iam_access_token] = nil
      defaults[:iam_url] = nil
      args = defaults.merge(args)
      args[:vcap_services_name] = "watson_vision_combined"
      super
      @version = args[:version]
      args[:display_name] = "Visual Recognition"
    end

    #########################
    # General
    #########################

    ##
    # @!method classify(images_file: nil, images_filename: nil, images_file_content_type: nil, url: nil, threshold: nil, owners: nil, classifier_ids: nil, accept_language: nil)
    # Classify images.
    # Classify images with built-in or custom classifiers.
    # @param images_file [File] An image file (.gif, .jpg, .png, .tif) or .zip file with images. Maximum image
    #   size is 10 MB. Include no more than 20 images and limit the .zip file to 100 MB.
    #   Encode the image and .zip file names in UTF-8 if they contain non-ASCII
    #   characters. The service assumes UTF-8 encoding if it encounters non-ASCII
    #   characters.
    #
    #   You can also include an image with the **url** parameter.
    # @param images_filename [String] The filename for images_file.
    # @param images_file_content_type [String] The content type of images_file.
    # @param url [String] The URL of an image (.gif, .jpg, .png, .tif) to analyze. The minimum recommended
    #   pixel density is 32X32 pixels, but the service tends to perform better with images
    #   that are at least 224 x 224 pixels. The maximum image size is 10 MB.
    #
    #   You can also include images with the **images_file** parameter.
    # @param threshold [Float] The minimum score a class must have to be displayed in the response. Set the
    #   threshold to `0.0` to return all identified classes.
    # @param owners [Array[String]] The categories of classifiers to apply. The **classifier_ids** parameter overrides
    #   **owners**, so make sure that **classifier_ids** is empty.
    #   - Use `IBM` to classify against the `default` general classifier. You get the same
    #   result if both **classifier_ids** and **owners** parameters are empty.
    #   - Use `me` to classify against all your custom classifiers. However, for better
    #   performance use **classifier_ids** to specify the specific custom classifiers to
    #   apply.
    #   - Use both `IBM` and `me` to analyze the image against both classifier categories.
    # @param classifier_ids [Array[String]] Which classifiers to apply. Overrides the **owners** parameter. You can specify
    #   both custom and built-in classifier IDs. The built-in `default` classifier is used
    #   if both **classifier_ids** and **owners** parameters are empty.
    #
    #   The following built-in classifier IDs require no training:
    #   - `default`: Returns classes from thousands of general tags.
    #   - `food`: Enhances specificity and accuracy for images of food items.
    #   - `explicit`: Evaluates whether the image might be pornographic.
    # @param accept_language [String] The desired language of parts of the response. See the response for details.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def classify(images_file: nil, images_filename: nil, images_file_content_type: nil, url: nil, threshold: nil, owners: nil, classifier_ids: nil, accept_language: nil)
      headers = {
        "Accept-Language" => accept_language
      }
      sdk_headers = Common.new.get_sdk_headers("watson_vision_combined", "V3", "classify")
      headers.merge!(sdk_headers)

      params = {
        "version" => @version
      }

      form_data = {}

      unless images_file.nil?
        unless images_file.instance_of?(StringIO) || images_file.instance_of?(File)
          images_file = images_file.respond_to?(:to_json) ? StringIO.new(images_file.to_json) : StringIO.new(images_file)
        end
        images_filename = images_file.path if images_filename.nil? && images_file.respond_to?(:path)
        form_data[:images_file] = HTTP::FormData::File.new(images_file, content_type: images_file_content_type.nil? ? "application/octet-stream" : images_file_content_type, filename: images_filename)
      end

      classifier_ids *= "," unless classifier_ids.nil?
      owners *= "," unless owners.nil?

      form_data[:url] = HTTP::FormData::Part.new(url.to_s, content_type: "text/plain") unless url.nil?

      form_data[:threshold] = HTTP::FormData::Part.new(threshold.to_s, content_type: "application/json") unless threshold.nil?

      form_data[:owners] = HTTP::FormData::Part.new(owners, content_type: "application/json") unless owners.nil?

      form_data[:classifier_ids] = HTTP::FormData::Part.new(classifier_ids, content_type: "application/json") unless classifier_ids.nil?

      method_url = "/v3/classify"

      response = request(
        method: "POST",
        url: method_url,
        headers: headers,
        params: params,
        form: form_data,
        accept_json: true
      )
      response
    end
    #########################
    # Face
    #########################

    ##
    # @!method detect_faces(images_file: nil, images_filename: nil, images_file_content_type: nil, url: nil, accept_language: nil)
    # Detect faces in images.
    # **Important:** On April 2, 2018, the identity information in the response to calls
    #   to the Face model was removed. The identity information refers to the `name` of
    #   the person, `score`, and `type_hierarchy` knowledge graph. For details about the
    #   enhanced Face model, see the [Release
    #   notes](https://cloud.ibm.com/docs/services/visual-recognition/release-notes.html#2april2018).
    #
    #   Analyze and get data about faces in images. Responses can include estimated age
    #   and gender. This feature uses a built-in model, so no training is necessary. The
    #   Detect faces method does not support general biometric facial recognition.
    #
    #   Supported image formats include .gif, .jpg, .png, and .tif. The maximum image size
    #   is 10 MB. The minimum recommended pixel density is 32X32 pixels, but the service
    #   tends to perform better with images that are at least 224 x 224 pixels.
    # @param images_file [File] An image file (gif, .jpg, .png, .tif.) or .zip file with images. Limit the .zip
    #   file to 100 MB. You can include a maximum of 15 images in a request.
    #
    #   Encode the image and .zip file names in UTF-8 if they contain non-ASCII
    #   characters. The service assumes UTF-8 encoding if it encounters non-ASCII
    #   characters.
    #
    #   You can also include an image with the **url** parameter.
    # @param images_filename [String] The filename for images_file.
    # @param images_file_content_type [String] The content type of images_file.
    # @param url [String] The URL of an image to analyze. Must be in .gif, .jpg, .png, or .tif format. The
    #   minimum recommended pixel density is 32X32 pixels, but the service tends to
    #   perform better with images that are at least 224 x 224 pixels. The maximum image
    #   size is 10 MB. Redirects are followed, so you can use a shortened URL.
    #
    #   You can also include images with the **images_file** parameter.
    # @param accept_language [String] The desired language of parts of the response. See the response for details.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def detect_faces(images_file: nil, images_filename: nil, images_file_content_type: nil, url: nil, accept_language: nil)
      headers = {
        "Accept-Language" => accept_language
      }
      sdk_headers = Common.new.get_sdk_headers("watson_vision_combined", "V3", "detect_faces")
      headers.merge!(sdk_headers)

      params = {
        "version" => @version
      }

      form_data = {}

      unless images_file.nil?
        unless images_file.instance_of?(StringIO) || images_file.instance_of?(File)
          images_file = images_file.respond_to?(:to_json) ? StringIO.new(images_file.to_json) : StringIO.new(images_file)
        end
        images_filename = images_file.path if images_filename.nil? && images_file.respond_to?(:path)
        form_data[:images_file] = HTTP::FormData::File.new(images_file, content_type: images_file_content_type.nil? ? "application/octet-stream" : images_file_content_type, filename: images_filename)
      end

      form_data[:url] = HTTP::FormData::Part.new(url.to_s, content_type: "text/plain") unless url.nil?

      method_url = "/v3/detect_faces"

      response = request(
        method: "POST",
        url: method_url,
        headers: headers,
        params: params,
        form: form_data,
        accept_json: true
      )
      response
    end
    #########################
    # Custom
    #########################

    ##
    # @!method create_classifier(name:, positive_examples:, negative_examples: nil, negative_examples_filename: nil)
    # Create a classifier.
    # Train a new multi-faceted classifier on the uploaded image data. Create your
    #   custom classifier with positive or negative examples. Include at least two sets of
    #   examples, either two positive example files or one positive and one negative file.
    #   You can upload a maximum of 256 MB per call.
    #
    #   Encode all names in UTF-8 if they contain non-ASCII characters (.zip and image
    #   file names, and classifier and class names). The service assumes UTF-8 encoding if
    #   it encounters non-ASCII characters.
    # @param name [String] The name of the new classifier. Encode special characters in UTF-8.
    # @param positive_examples [File] A .zip file of images that depict the visual subject of a class in the new
    #   classifier. You can include more than one positive example file in a call.
    #
    #   Specify the parameter name by appending `_positive_examples` to the class name.
    #   For example, `goldenretriever_positive_examples` creates the class
    #   **goldenretriever**.
    #
    #   Include at least 10 images in .jpg or .png format. The minimum recommended image
    #   resolution is 32X32 pixels. The maximum number of images is 10,000 images or 100
    #   MB per .zip file.
    #
    #   Encode special characters in the file name in UTF-8.
    # @param negative_examples [File] A .zip file of images that do not depict the visual subject of any of the classes
    #   of the new classifier. Must contain a minimum of 10 images.
    #
    #   Encode special characters in the file name in UTF-8.
    # @param negative_examples_filename [String] The filename for negative_examples.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def create_classifier(name:, positive_examples:, negative_examples: nil, negative_examples_filename: nil)
      raise ArgumentError.new("name must be provided") if name.nil?

      raise ArgumentError.new("positive_examples must be a hash") unless positive_examples.is_a?(Hash)
      raise ArgumentError.new("positive_examples must have at least one hash entry") if positive_examples.empty?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("watson_vision_combined", "V3", "create_classifier")
      headers.merge!(sdk_headers)

      params = {
        "version" => @version
      }

      form_data = {}

      form_data[:name] = HTTP::FormData::Part.new(name.to_s, content_type: "text/plain")

      positive_examples&.each do |key, value|
        part_name = "%s_positive_examples" % key.to_s
        unless value.instance_of?(StringIO) || value.instance_of?(File)
          value = value.respond_to?(:to_json) ? StringIO.new(value.to_json) : StringIO.new(value)
        end
        filename = value.path if value.respond_to?(:path)
        form_data[part_name.to_sym] = HTTP::FormData::File.new(value, content_type: "application/octet-stream", filename: filename)
      end

      unless negative_examples.nil?
        unless negative_examples.instance_of?(StringIO) || negative_examples.instance_of?(File)
          negative_examples = negative_examples.respond_to?(:to_json) ? StringIO.new(negative_examples.to_json) : StringIO.new(negative_examples)
        end
        negative_examples_filename = negative_examples.path if negative_examples_filename.nil? && negative_examples.respond_to?(:path)
        form_data[:negative_examples] = HTTP::FormData::File.new(negative_examples, content_type: "application/octet-stream", filename: negative_examples_filename)
      end

      method_url = "/v3/classifiers"

      response = request(
        method: "POST",
        url: method_url,
        headers: headers,
        params: params,
        form: form_data,
        accept_json: true
      )
      response
    end

    ##
    # @!method delete_classifier(classifier_id:)
    # Delete a classifier.
    # @param classifier_id [String] The ID of the classifier.
    # @return [nil]
    def delete_classifier(classifier_id:)
      raise ArgumentError.new("classifier_id must be provided") if classifier_id.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("watson_vision_combined", "V3", "delete_classifier")
      headers.merge!(sdk_headers)

      params = {
        "version" => @version
      }

      method_url = "/v3/classifiers/%s" % [ERB::Util.url_encode(classifier_id)]

      request(
        method: "DELETE",
        url: method_url,
        headers: headers,
        params: params,
        accept_json: true
      )
      nil
    end

    ##
    # @!method get_classifier(classifier_id:)
    # Retrieve classifier details.
    # Retrieve information about a custom classifier.
    # @param classifier_id [String] The ID of the classifier.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def get_classifier(classifier_id:)
      raise ArgumentError.new("classifier_id must be provided") if classifier_id.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("watson_vision_combined", "V3", "get_classifier")
      headers.merge!(sdk_headers)

      params = {
        "version" => @version
      }

      method_url = "/v3/classifiers/%s" % [ERB::Util.url_encode(classifier_id)]

      response = request(
        method: "GET",
        url: method_url,
        headers: headers,
        params: params,
        accept_json: true
      )
      response
    end

    ##
    # @!method list_classifiers(verbose: nil)
    # Retrieve a list of classifiers.
    # @param verbose [Boolean] Specify `true` to return details about the classifiers. Omit this parameter to
    #   return a brief list of classifiers.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def list_classifiers(verbose: nil)
      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("watson_vision_combined", "V3", "list_classifiers")
      headers.merge!(sdk_headers)

      params = {
        "version" => @version,
        "verbose" => verbose
      }

      method_url = "/v3/classifiers"

      response = request(
        method: "GET",
        url: method_url,
        headers: headers,
        params: params,
        accept_json: true
      )
      response
    end

    ##
    # @!method update_classifier(classifier_id:, positive_examples: nil, negative_examples: nil, negative_examples_filename: nil)
    # Update a classifier.
    # Update a custom classifier by adding new positive or negative classes or by adding
    #   new images to existing classes. You must supply at least one set of positive or
    #   negative examples. For details, see [Updating custom
    #   classifiers](https://cloud.ibm.com/docs/services/visual-recognition/customizing.html#updating-custom-classifiers).
    #
    #   Encode all names in UTF-8 if they contain non-ASCII characters (.zip and image
    #   file names, and classifier and class names). The service assumes UTF-8 encoding if
    #   it encounters non-ASCII characters.
    #
    #   **Tip:** Don't make retraining calls on a classifier until the status is ready.
    #   When you submit retraining requests in parallel, the last request overwrites the
    #   previous requests. The retrained property shows the last time the classifier
    #   retraining finished.
    # @param classifier_id [String] The ID of the classifier.
    # @param positive_examples [File] A .zip file of images that depict the visual subject of a class in the classifier.
    #   The positive examples create or update classes in the classifier. You can include
    #   more than one positive example file in a call.
    #
    #   Specify the parameter name by appending `_positive_examples` to the class name.
    #   For example, `goldenretriever_positive_examples` creates the class
    #   `goldenretriever`.
    #
    #   Include at least 10 images in .jpg or .png format. The minimum recommended image
    #   resolution is 32X32 pixels. The maximum number of images is 10,000 images or 100
    #   MB per .zip file.
    #
    #   Encode special characters in the file name in UTF-8.
    # @param negative_examples [File] A .zip file of images that do not depict the visual subject of any of the classes
    #   of the new classifier. Must contain a minimum of 10 images.
    #
    #   Encode special characters in the file name in UTF-8.
    # @param negative_examples_filename [String] The filename for negative_examples.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def update_classifier(classifier_id:, positive_examples: nil, negative_examples: nil, negative_examples_filename: nil)
      raise ArgumentError.new("classifier_id must be provided") if classifier_id.nil?

      raise ArgumentError.new("positive_examples must be a hash") unless positive_examples.nil? || positive_examples.is_a?(Hash)

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("watson_vision_combined", "V3", "update_classifier")
      headers.merge!(sdk_headers)

      params = {
        "version" => @version
      }

      form_data = {}

      positive_examples&.each do |key, value|
        part_name = "%s_positive_examples" % key.to_s
        unless value.instance_of?(StringIO) || value.instance_of?(File)
          value = value.respond_to?(:to_json) ? StringIO.new(value.to_json) : StringIO.new(value)
        end
        filename = value.path if value.respond_to?(:path)
        form_data[part_name.to_sym] = HTTP::FormData::File.new(value, content_type: "application/octet-stream", filename: filename)
      end

      unless negative_examples.nil?
        unless negative_examples.instance_of?(StringIO) || negative_examples.instance_of?(File)
          negative_examples = negative_examples.respond_to?(:to_json) ? StringIO.new(negative_examples.to_json) : StringIO.new(negative_examples)
        end
        negative_examples_filename = negative_examples.path if negative_examples_filename.nil? && negative_examples.respond_to?(:path)
        form_data[:negative_examples] = HTTP::FormData::File.new(negative_examples, content_type: "application/octet-stream", filename: negative_examples_filename)
      end

      method_url = "/v3/classifiers/%s" % [ERB::Util.url_encode(classifier_id)]

      response = request(
        method: "POST",
        url: method_url,
        headers: headers,
        params: params,
        form: form_data,
        accept_json: true
      )
      response
    end
    #########################
    # Core ML
    #########################

    ##
    # @!method get_core_ml_model(classifier_id:)
    # Retrieve a Core ML model of a classifier.
    # Download a Core ML model file (.mlmodel) of a custom classifier that returns
    #   <tt>\"core_ml_enabled\": true</tt> in the classifier details.
    # @param classifier_id [String] The ID of the classifier.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def get_core_ml_model(classifier_id:)
      raise ArgumentError.new("classifier_id must be provided") if classifier_id.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("watson_vision_combined", "V3", "get_core_ml_model")
      headers.merge!(sdk_headers)

      params = {
        "version" => @version
      }

      method_url = "/v3/classifiers/%s/core_ml_model" % [ERB::Util.url_encode(classifier_id)]

      response = request(
        method: "GET",
        url: method_url,
        headers: headers,
        params: params,
        accept_json: false
      )
      response
    end
    #########################
    # User data
    #########################

    ##
    # @!method delete_user_data(customer_id:)
    # Delete labeled data.
    # Deletes all data associated with a specified customer ID. The method has no effect
    #   if no data is associated with the customer ID.
    #
    #   You associate a customer ID with data by passing the `X-Watson-Metadata` header
    #   with a request that passes data. For more information about personal data and
    #   customer IDs, see [Information
    #   security](https://cloud.ibm.com/docs/services/visual-recognition/information-security.html).
    # @param customer_id [String] The customer ID for which all data is to be deleted.
    # @return [nil]
    def delete_user_data(customer_id:)
      raise ArgumentError.new("customer_id must be provided") if customer_id.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("watson_vision_combined", "V3", "delete_user_data")
      headers.merge!(sdk_headers)

      params = {
        "version" => @version,
        "customer_id" => customer_id
      }

      method_url = "/v3/user_data"

      request(
        method: "DELETE",
        url: method_url,
        headers: headers,
        params: params,
        accept_json: true
      )
      nil
    end
  end
end


# frozen_string_literal: true

# Copyright 2018 IBM All Rights Reserved.
#
# Licensed 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.

# IBM Watson™ Natural Language Classifier uses machine learning algorithms to
# return the top matching predefined classes for short text input. You create and train a
# classifier to connect predefined classes to example texts so that the service can apply
# those classes to new inputs.

require "concurrent"
require "erb"
require "json"
require "ibm_cloud_sdk_core"
require_relative "./common.rb"

# Module for the Watson APIs
module IBMWatson
  ##
  # The Natural Language Classifier V1 service.
  class NaturalLanguageClassifierV1 < IBMCloudSdkCore::BaseService
    include Concurrent::Async
    ##
    # @!method initialize(args)
    # Construct a new client for the Natural Language Classifier service.
    #
    # @param args [Hash] The args to initialize with
    # @option args url [String] The base url to use when contacting the service (e.g.
    #   "https://gateway.watsonplatform.net/natural-language-classifier/api").
    #   The base url may differ between Bluemix regions.
    # @option args username [String] The username used to authenticate with the service.
    #   Username and password credentials are only required to run your
    #   application locally or outside of Bluemix. When running on
    #   Bluemix, the credentials will be automatically loaded from the
    #   `VCAP_SERVICES` environment variable.
    # @option args password [String] The password used to authenticate with the service.
    #   Username and password credentials are only required to run your
    #   application locally or outside of Bluemix. When running on
    #   Bluemix, the credentials will be automatically loaded from the
    #   `VCAP_SERVICES` environment variable.
    # @option args iam_apikey [String] An API key that can be used to request IAM tokens. If
    #   this API key is provided, the SDK will manage the token and handle the
    #   refreshing.
    # @option args iam_access_token [String] An IAM access token is fully managed by the application.
    #   Responsibility falls on the application to refresh the token, either before
    #   it expires or reactively upon receiving a 401 from the service as any requests
    #   made with an expired token will fail.
    # @option args iam_url [String] An optional URL for the IAM service API. Defaults to
    #   'https://iam.ng.bluemix.net/identity/token'.
    def initialize(args = {})
      @__async_initialized__ = false
      defaults = {}
      defaults[:url] = "https://gateway.watsonplatform.net/natural-language-classifier/api"
      defaults[:username] = nil
      defaults[:password] = nil
      defaults[:iam_apikey] = nil
      defaults[:iam_access_token] = nil
      defaults[:iam_url] = nil
      args = defaults.merge(args)
      args[:vcap_services_name] = "natural_language_classifier"
      super
      args[:display_name] = "Natural Language Classifier"
    end

    #########################
    # Classify text
    #########################

    ##
    # @!method classify(classifier_id:, text:)
    # Classify a phrase.
    # Returns label information for the input. The status must be `Available` before you
    #   can use the classifier to classify text.
    # @param classifier_id [String] Classifier ID to use.
    # @param text [String] The submitted phrase. The maximum length is 2048 characters.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def classify(classifier_id:, text:)
      raise ArgumentError.new("classifier_id must be provided") if classifier_id.nil?

      raise ArgumentError.new("text must be provided") if text.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("natural_language_classifier", "V1", "classify")
      headers.merge!(sdk_headers)

      data = {
        "text" => text
      }

      method_url = "/v1/classifiers/%s/classify" % [ERB::Util.url_encode(classifier_id)]

      response = request(
        method: "POST",
        url: method_url,
        headers: headers,
        json: data,
        accept_json: true
      )
      response
    end

    ##
    # @!method classify_collection(classifier_id:, collection:)
    # Classify multiple phrases.
    # Returns label information for multiple phrases. The status must be `Available`
    #   before you can use the classifier to classify text.
    #
    #   Note that classifying Japanese texts is a beta feature.
    # @param classifier_id [String] Classifier ID to use.
    # @param collection [Array[ClassifyInput]] The submitted phrases.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def classify_collection(classifier_id:, collection:)
      raise ArgumentError.new("classifier_id must be provided") if classifier_id.nil?

      raise ArgumentError.new("collection must be provided") if collection.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("natural_language_classifier", "V1", "classify_collection")
      headers.merge!(sdk_headers)

      data = {
        "collection" => collection
      }

      method_url = "/v1/classifiers/%s/classify_collection" % [ERB::Util.url_encode(classifier_id)]

      response = request(
        method: "POST",
        url: method_url,
        headers: headers,
        json: data,
        accept_json: true
      )
      response
    end
    #########################
    # Manage classifiers
    #########################

    ##
    # @!method create_classifier(metadata:, training_data:)
    # Create classifier.
    # Sends data to create and train a classifier and returns information about the new
    #   classifier.
    # @param metadata [File] Metadata in JSON format. The metadata identifies the language of the data, and an
    #   optional name to identify the classifier. Specify the language with the 2-letter
    #   primary language code as assigned in ISO standard 639.
    #
    #   Supported languages are English (`en`), Arabic (`ar`), French (`fr`), German,
    #   (`de`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Brazilian Portuguese
    #   (`pt`), and Spanish (`es`).
    # @param training_data [File] Training data in CSV format. Each text value must have at least one class. The
    #   data can include up to 3,000 classes and 20,000 records. For details, see [Data
    #   preparation](https://cloud.ibm.com/docs/services/natural-language-classifier/using-your-data.html).
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def create_classifier(metadata:, training_data:)
      raise ArgumentError.new("metadata must be provided") if metadata.nil?

      raise ArgumentError.new("training_data must be provided") if training_data.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("natural_language_classifier", "V1", "create_classifier")
      headers.merge!(sdk_headers)

      form_data = {}

      unless metadata.instance_of?(StringIO) || metadata.instance_of?(File)
        metadata = metadata.respond_to?(:to_json) ? StringIO.new(metadata.to_json) : StringIO.new(metadata)
      end
      form_data[:training_metadata] = HTTP::FormData::File.new(metadata, content_type: "application/json", filename: metadata.respond_to?(:path) ? metadata.path : nil)

      unless training_data.instance_of?(StringIO) || training_data.instance_of?(File)
        training_data = training_data.respond_to?(:to_json) ? StringIO.new(training_data.to_json) : StringIO.new(training_data)
      end
      form_data[:training_data] = HTTP::FormData::File.new(training_data, content_type: "text/csv", filename: training_data.respond_to?(:path) ? training_data.path : nil)

      method_url = "/v1/classifiers"

      response = request(
        method: "POST",
        url: method_url,
        headers: headers,
        form: form_data,
        accept_json: true
      )
      response
    end

    ##
    # @!method delete_classifier(classifier_id:)
    # Delete classifier.
    # @param classifier_id [String] Classifier ID to delete.
    # @return [nil]
    def delete_classifier(classifier_id:)
      raise ArgumentError.new("classifier_id must be provided") if classifier_id.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("natural_language_classifier", "V1", "delete_classifier")
      headers.merge!(sdk_headers)

      method_url = "/v1/classifiers/%s" % [ERB::Util.url_encode(classifier_id)]

      request(
        method: "DELETE",
        url: method_url,
        headers: headers,
        accept_json: true
      )
      nil
    end

    ##
    # @!method get_classifier(classifier_id:)
    # Get information about a classifier.
    # Returns status and other information about a classifier.
    # @param classifier_id [String] Classifier ID to query.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def get_classifier(classifier_id:)
      raise ArgumentError.new("classifier_id must be provided") if classifier_id.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("natural_language_classifier", "V1", "get_classifier")
      headers.merge!(sdk_headers)

      method_url = "/v1/classifiers/%s" % [ERB::Util.url_encode(classifier_id)]

      response = request(
        method: "GET",
        url: method_url,
        headers: headers,
        accept_json: true
      )
      response
    end

    ##
    # @!method list_classifiers
    # List classifiers.
    # Returns an empty array if no classifiers are available.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def list_classifiers
      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("natural_language_classifier", "V1", "list_classifiers")
      headers.merge!(sdk_headers)

      method_url = "/v1/classifiers"

      response = request(
        method: "GET",
        url: method_url,
        headers: headers,
        accept_json: true
      )
      response
    end
  end
end


# frozen_string_literal: true

# Copyright 2018 IBM All Rights Reserved.
#
# Licensed 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.

# The IBM Watson™ Personality Insights service enables applications to derive
# insights from social media, enterprise data, or other digital communications. The
# service uses linguistic analytics to infer individuals' intrinsic personality
# characteristics, including Big Five, Needs, and Values, from digital communications such
# as email, text messages, tweets, and forum posts.
#
# The service can automatically infer, from potentially noisy social media, portraits of
# individuals that reflect their personality characteristics. The service can infer
# consumption preferences based on the results of its analysis and, for JSON content that
# is timestamped, can report temporal behavior.
# * For information about the meaning of the models that the service uses to describe
# personality characteristics, see [Personality
# models](https://cloud.ibm.com/docs/services/personality-insights/models.html).
# * For information about the meaning of the consumption preferences, see [Consumption
# preferences](https://cloud.ibm.com/docs/services/personality-insights/preferences.html).
#
#
# **Note:** Request logging is disabled for the Personality Insights service. Regardless
# of whether you set the `X-Watson-Learning-Opt-Out` request header, the service does not
# log or retain data from requests and responses.

require "concurrent"
require "erb"
require "json"
require "ibm_cloud_sdk_core"
require_relative "./common.rb"

# Module for the Watson APIs
module IBMWatson
  ##
  # The Personality Insights V3 service.
  class PersonalityInsightsV3 < IBMCloudSdkCore::BaseService
    include Concurrent::Async
    ##
    # @!method initialize(args)
    # Construct a new client for the Personality Insights service.
    #
    # @param args [Hash] The args to initialize with
    # @option args version [String] The API version date to use with the service, in
    #   "YYYY-MM-DD" format. Whenever the API is changed in a backwards
    #   incompatible way, a new minor version of the API is released.
    #   The service uses the API version for the date you specify, or
    #   the most recent version before that date. Note that you should
    #   not programmatically specify the current date at runtime, in
    #   case the API has been updated since your application's release.
    #   Instead, specify a version date that is compatible with your
    #   application, and don't change it until your application is
    #   ready for a later version.
    # @option args url [String] The base url to use when contacting the service (e.g.
    #   "https://gateway.watsonplatform.net/personality-insights/api").
    #   The base url may differ between Bluemix regions.
    # @option args username [String] The username used to authenticate with the service.
    #   Username and password credentials are only required to run your
    #   application locally or outside of Bluemix. When running on
    #   Bluemix, the credentials will be automatically loaded from the
    #   `VCAP_SERVICES` environment variable.
    # @option args password [String] The password used to authenticate with the service.
    #   Username and password credentials are only required to run your
    #   application locally or outside of Bluemix. When running on
    #   Bluemix, the credentials will be automatically loaded from the
    #   `VCAP_SERVICES` environment variable.
    # @option args iam_apikey [String] An API key that can be used to request IAM tokens. If
    #   this API key is provided, the SDK will manage the token and handle the
    #   refreshing.
    # @option args iam_access_token [String] An IAM access token is fully managed by the application.
    #   Responsibility falls on the application to refresh the token, either before
    #   it expires or reactively upon receiving a 401 from the service as any requests
    #   made with an expired token will fail.
    # @option args iam_url [String] An optional URL for the IAM service API. Defaults to
    #   'https://iam.ng.bluemix.net/identity/token'.
    def initialize(args = {})
      @__async_initialized__ = false
      defaults = {}
      defaults[:version] = nil
      defaults[:url] = "https://gateway.watsonplatform.net/personality-insights/api"
      defaults[:username] = nil
      defaults[:password] = nil
      defaults[:iam_apikey] = nil
      defaults[:iam_access_token] = nil
      defaults[:iam_url] = nil
      args = defaults.merge(args)
      args[:vcap_services_name] = "personality_insights"
      super
      @version = args[:version]
      args[:display_name] = "Personality Insights"
    end

    #########################
    # Methods
    #########################

    ##
    # @!method profile(content:, accept:, content_language: nil, accept_language: nil, raw_scores: nil, csv_headers: nil, consumption_preferences: nil, content_type: nil)
    # Get profile.
    # Generates a personality profile for the author of the input text. The service
    #   accepts a maximum of 20 MB of input content, but it requires much less text to
    #   produce an accurate profile. The service can analyze text in Arabic, English,
    #   Japanese, Korean, or Spanish. It can return its results in a variety of languages.
    #
    #
    #   **See also:**
    #   * [Requesting a
    #   profile](https://cloud.ibm.com/docs/services/personality-insights/input.html)
    #   * [Providing sufficient
    #   input](https://cloud.ibm.com/docs/services/personality-insights/input.html#sufficient)
    #
    #
    #   ### Content types
    #
    #    You can provide input content as plain text (`text/plain`), HTML (`text/html`),
    #   or JSON (`application/json`) by specifying the **Content-Type** parameter. The
    #   default is `text/plain`.
    #   * Per the JSON specification, the default character encoding for JSON content is
    #   effectively always UTF-8.
    #   * Per the HTTP specification, the default encoding for plain text and HTML is
    #   ISO-8859-1 (effectively, the ASCII character set).
    #
    #   When specifying a content type of plain text or HTML, include the `charset`
    #   parameter to indicate the character encoding of the input text; for example,
    #   `Content-Type: text/plain;charset=utf-8`.
    #
    #   **See also:** [Specifying request and response
    #   formats](https://cloud.ibm.com/docs/services/personality-insights/input.html#formats)
    #
    #
    #   ### Accept types
    #
    #    You must request a response as JSON (`application/json`) or comma-separated
    #   values (`text/csv`) by specifying the **Accept** parameter. CSV output includes a
    #   fixed number of columns. Set the **csv_headers** parameter to `true` to request
    #   optional column headers for CSV output.
    #
    #   **See also:**
    #   * [Understanding a JSON
    #   profile](https://cloud.ibm.com/docs/services/personality-insights/output.html)
    #   * [Understanding a CSV
    #   profile](https://cloud.ibm.com/docs/services/personality-insights/output-csv.html).
    # @param content [Content] A maximum of 20 MB of content to analyze, though the service requires much less
    #   text; for more information, see [Providing sufficient
    #   input](https://cloud.ibm.com/docs/services/personality-insights/input.html#sufficient).
    #   For JSON input, provide an object of type `Content`.
    # @param accept [String] The type of the response. For more information, see **Accept types** in the method
    #   description.
    # @param content_language [String] The language of the input text for the request: Arabic, English, Japanese, Korean,
    #   or Spanish. Regional variants are treated as their parent language; for example,
    #   `en-US` is interpreted as `en`.
    #
    #   The effect of the **Content-Language** parameter depends on the **Content-Type**
    #   parameter. When **Content-Type** is `text/plain` or `text/html`,
    #   **Content-Language** is the only way to specify the language. When
    #   **Content-Type** is `application/json`, **Content-Language** overrides a language
    #   specified with the `language` parameter of a `ContentItem` object, and content
    #   items that specify a different language are ignored; omit this parameter to base
    #   the language on the specification of the content items. You can specify any
    #   combination of languages for **Content-Language** and **Accept-Language**.
    # @param accept_language [String] The desired language of the response. For two-character arguments, regional
    #   variants are treated as their parent language; for example, `en-US` is interpreted
    #   as `en`. You can specify any combination of languages for the input and response
    #   content.
    # @param raw_scores [Boolean] Indicates whether a raw score in addition to a normalized percentile is returned
    #   for each characteristic; raw scores are not compared with a sample population. By
    #   default, only normalized percentiles are returned.
    # @param csv_headers [Boolean] Indicates whether column labels are returned with a CSV response. By default, no
    #   column labels are returned. Applies only when the response type is CSV
    #   (`text/csv`).
    # @param consumption_preferences [Boolean] Indicates whether consumption preferences are returned with the results. By
    #   default, no consumption preferences are returned.
    # @param content_type [String] The type of the input. For more information, see **Content types** in the method
    #   description.
    #
    #   Default: `text/plain`.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def profile(content:, accept:, content_language: nil, accept_language: nil, raw_scores: nil, csv_headers: nil, consumption_preferences: nil, content_type: nil)
      raise ArgumentError.new("content must be provided") if content.nil?

      raise ArgumentError.new("accept must be provided") if accept.nil?

      headers = {
        "Accept" => accept,
        "Content-Language" => content_language,
        "Accept-Language" => accept_language,
        "Content-Type" => content_type
      }
      sdk_headers = Common.new.get_sdk_headers("personality_insights", "V3", "profile")
      headers.merge!(sdk_headers)

      params = {
        "version" => @version,
        "raw_scores" => raw_scores,
        "csv_headers" => csv_headers,
        "consumption_preferences" => consumption_preferences
      }

      if content_type.start_with?("application/json") && content.instance_of?(Hash)
        data = content.to_json
      else
        data = content
      end

      method_url = "/v3/profile"

      response = request(
        method: "POST",
        url: method_url,
        headers: headers,
        params: params,
        data: data,
        accept_json: true
      )
      response
    end
  end
end


# frozen_string_literal: true

# Copyright 2018 IBM All Rights Reserved.
#
# Licensed 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.

# ### Service Overview
# The IBM® Text to Speech service provides APIs that use IBM's speech-synthesis
# capabilities to synthesize text into natural-sounding speech in a variety of languages,
# dialects, and voices. The service supports at least one male or female voice, sometimes
# both, for each language. The audio is streamed back to the client with minimal delay.
#
# For speech synthesis, the service supports a synchronous HTTP Representational State
# Transfer (REST) interface. It also supports a WebSocket interface that provides both
# plain text and SSML input, including the SSML <mark> element and word timings.
# SSML is an XML-based markup language that provides text annotation for speech-synthesis
# applications.
#
# The service also offers a customization interface. You can use the interface to define
# sounds-like or phonetic translations for words. A sounds-like translation consists of
# one or more words that, when combined, sound like the word. A phonetic translation is
# based on the SSML phoneme format for representing a word. You can specify a phonetic
# translation in standard International Phonetic Alphabet (IPA) representation or in the
# proprietary IBM Symbolic Phonetic Representation (SPR).

require "concurrent"
require "erb"
require "json"
require "ibm_cloud_sdk_core"
require_relative "./common.rb"

# Module for the Watson APIs
module IBMWatson
  ##
  # The Text to Speech V1 service.
  class TextToSpeechV1 < IBMCloudSdkCore::BaseService
    include Concurrent::Async
    ##
    # @!method initialize(args)
    # Construct a new client for the Text to Speech service.
    #
    # @param args [Hash] The args to initialize with
    # @option args url [String] The base url to use when contacting the service (e.g.
    #   "https://stream.watsonplatform.net/text-to-speech/api").
    #   The base url may differ between Bluemix regions.
    # @option args username [String] The username used to authenticate with the service.
    #   Username and password credentials are only required to run your
    #   application locally or outside of Bluemix. When running on
    #   Bluemix, the credentials will be automatically loaded from the
    #   `VCAP_SERVICES` environment variable.
    # @option args password [String] The password used to authenticate with the service.
    #   Username and password credentials are only required to run your
    #   application locally or outside of Bluemix. When running on
    #   Bluemix, the credentials will be automatically loaded from the
    #   `VCAP_SERVICES` environment variable.
    # @option args iam_apikey [String] An API key that can be used to request IAM tokens. If
    #   this API key is provided, the SDK will manage the token and handle the
    #   refreshing.
    # @option args iam_access_token [String] An IAM access token is fully managed by the application.
    #   Responsibility falls on the application to refresh the token, either before
    #   it expires or reactively upon receiving a 401 from the service as any requests
    #   made with an expired token will fail.
    # @option args iam_url [String] An optional URL for the IAM service API. Defaults to
    #   'https://iam.ng.bluemix.net/identity/token'.
    def initialize(args = {})
      @__async_initialized__ = false
      defaults = {}
      defaults[:url] = "https://stream.watsonplatform.net/text-to-speech/api"
      defaults[:username] = nil
      defaults[:password] = nil
      defaults[:iam_apikey] = nil
      defaults[:iam_access_token] = nil
      defaults[:iam_url] = nil
      args = defaults.merge(args)
      args[:vcap_services_name] = "text_to_speech"
      super
      args[:display_name] = "Text to Speech"
    end

    #########################
    # Voices
    #########################

    ##
    # @!method get_voice(voice:, customization_id: nil)
    # Get a voice.
    # Gets information about the specified voice. The information includes the name,
    #   language, gender, and other details about the voice. Specify a customization ID to
    #   obtain information for that custom voice model of the specified voice. To list
    #   information about all available voices, use the **List voices** method.
    #
    #   **See also:** [Listing a specific
    #   voice](https://cloud.ibm.com/docs/services/text-to-speech/voices.html#listVoice).
    # @param voice [String] The voice for which information is to be returned.
    # @param customization_id [String] The customization ID (GUID) of a custom voice model for which information is to be
    #   returned. You must make the request with service credentials created for the
    #   instance of the service that owns the custom model. Omit the parameter to see
    #   information about the specified voice with no customization.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def get_voice(voice:, customization_id: nil)
      raise ArgumentError.new("voice must be provided") if voice.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "get_voice")
      headers.merge!(sdk_headers)

      params = {
        "customization_id" => customization_id
      }

      method_url = "/v1/voices/%s" % [ERB::Util.url_encode(voice)]

      response = request(
        method: "GET",
        url: method_url,
        headers: headers,
        params: params,
        accept_json: true
      )
      response
    end

    ##
    # @!method list_voices
    # List voices.
    # Lists all voices available for use with the service. The information includes the
    #   name, language, gender, and other details about the voice. To see information
    #   about a specific voice, use the **Get a voice** method.
    #
    #   **See also:** [Listing all available
    #   voices](https://cloud.ibm.com/docs/services/text-to-speech/voices.html#listVoices).
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def list_voices
      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "list_voices")
      headers.merge!(sdk_headers)

      method_url = "/v1/voices"

      response = request(
        method: "GET",
        url: method_url,
        headers: headers,
        accept_json: true
      )
      response
    end
    #########################
    # Synthesis
    #########################

    ##
    # @!method synthesize(text:, voice: nil, customization_id: nil, accept: nil)
    # Synthesize audio.
    # Synthesizes text to audio that is spoken in the specified voice. The service bases
    #   its understanding of the language for the input text on the specified voice. Use a
    #   voice that matches the language of the input text.
    #
    #   The method accepts a maximum of 5 KB of input text in the body of the request, and
    #   8 KB for the URL and headers. The 5 KB limit includes any SSML tags that you
    #   specify. The service returns the synthesized audio stream as an array of bytes.
    #
    #   **See also:** [The HTTP
    #   interface](https://cloud.ibm.com/docs/services/text-to-speech/http.html).
    #
    #   ### Audio formats (accept types)
    #
    #    The service can return audio in the following formats (MIME types).
    #   * Where indicated, you can optionally specify the sampling rate (`rate`) of the
    #   audio. You must specify a sampling rate for the `audio/l16` and `audio/mulaw`
    #   formats. A specified sampling rate must lie in the range of 8 kHz to 192 kHz.
    #   * For the `audio/l16` format, you can optionally specify the endianness
    #   (`endianness`) of the audio: `endianness=big-endian` or
    #   `endianness=little-endian`.
    #
    #   Use the `Accept` header or the `accept` parameter to specify the requested format
    #   of the response audio. If you omit an audio format altogether, the service returns
    #   the audio in Ogg format with the Opus codec (`audio/ogg;codecs=opus`). The service
    #   always returns single-channel audio.
    #   * `audio/basic`
    #
    #     The service returns audio with a sampling rate of 8000 Hz.
    #   * `audio/flac`
    #
    #     You can optionally specify the `rate` of the audio. The default sampling rate is
    #   22,050 Hz.
    #   * `audio/l16`
    #
    #     You must specify the `rate` of the audio. You can optionally specify the
    #   `endianness` of the audio. The default endianness is `little-endian`.
    #   * `audio/mp3`
    #
    #     You can optionally specify the `rate` of the audio. The default sampling rate is
    #   22,050 Hz.
    #   * `audio/mpeg`
    #
    #     You can optionally specify the `rate` of the audio. The default sampling rate is
    #   22,050 Hz.
    #   * `audio/mulaw`
    #
    #     You must specify the `rate` of the audio.
    #   * `audio/ogg`
    #
    #     The service returns the audio in the `vorbis` codec. You can optionally specify
    #   the `rate` of the audio. The default sampling rate is 22,050 Hz.
    #   * `audio/ogg;codecs=opus`
    #
    #     You can optionally specify the `rate` of the audio. The default sampling rate is
    #   22,050 Hz.
    #   * `audio/ogg;codecs=vorbis`
    #
    #     You can optionally specify the `rate` of the audio. The default sampling rate is
    #   22,050 Hz.
    #   * `audio/wav`
    #
    #     You can optionally specify the `rate` of the audio. The default sampling rate is
    #   22,050 Hz.
    #   * `audio/webm`
    #
    #     The service returns the audio in the `opus` codec. The service returns audio
    #   with a sampling rate of 48,000 Hz.
    #   * `audio/webm;codecs=opus`
    #
    #     The service returns audio with a sampling rate of 48,000 Hz.
    #   * `audio/webm;codecs=vorbis`
    #
    #     You can optionally specify the `rate` of the audio. The default sampling rate is
    #   22,050 Hz.
    #
    #   For more information about specifying an audio format, including additional
    #   details about some of the formats, see [Audio
    #   formats](https://cloud.ibm.com/docs/services/text-to-speech/audio-formats.html).
    #
    #   ### Warning messages
    #
    #    If a request includes invalid query parameters, the service returns a `Warnings`
    #   response header that provides messages about the invalid parameters. The warning
    #   includes a descriptive message and a list of invalid argument strings. For
    #   example, a message such as `\"Unknown arguments:\"` or `\"Unknown url query
    #   arguments:\"` followed by a list of the form `\"{invalid_arg_1},
    #   {invalid_arg_2}.\"` The request succeeds despite the warnings.
    # @param text [String] The text to synthesize.
    # @param voice [String] The voice to use for synthesis.
    # @param customization_id [String] The customization ID (GUID) of a custom voice model to use for the synthesis. If a
    #   custom voice model is specified, it is guaranteed to work only if it matches the
    #   language of the indicated voice. You must make the request with service
    #   credentials created for the instance of the service that owns the custom model.
    #   Omit the parameter to use the specified voice with no customization.
    # @param accept [String] The requested format (MIME type) of the audio. You can use the `Accept` header or
    #   the `accept` parameter to specify the audio format. For more information about
    #   specifying an audio format, see **Audio formats (accept types)** in the method
    #   description.
    #
    #   Default: `audio/ogg;codecs=opus`.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def synthesize(text:, voice: nil, customization_id: nil, accept: nil)
      raise ArgumentError.new("text must be provided") if text.nil?

      headers = {
        "Accept" => accept
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "synthesize")
      headers.merge!(sdk_headers)

      params = {
        "voice" => voice,
        "customization_id" => customization_id
      }

      data = {
        "text" => text
      }

      method_url = "/v1/synthesize"

      response = request(
        method: "POST",
        url: method_url,
        headers: headers,
        params: params,
        json: data,
        accept_json: false
      )
      response
    end
    #########################
    # Pronunciation
    #########################

    ##
    # @!method get_pronunciation(text:, voice: nil, format: nil, customization_id: nil)
    # Get pronunciation.
    # Gets the phonetic pronunciation for the specified word. You can request the
    #   pronunciation for a specific format. You can also request the pronunciation for a
    #   specific voice to see the default translation for the language of that voice or
    #   for a specific custom voice model to see the translation for that voice model.
    #
    #   **Note:** This method is currently a beta release.
    #
    #   **See also:** [Querying a word from a
    #   language](https://cloud.ibm.com/docs/services/text-to-speech/custom-entries.html#cuWordsQueryLanguage).
    # @param text [String] The word for which the pronunciation is requested.
    # @param voice [String] A voice that specifies the language in which the pronunciation is to be returned.
    #   All voices for the same language (for example, `en-US`) return the same
    #   translation.
    # @param format [String] The phoneme format in which to return the pronunciation. Omit the parameter to
    #   obtain the pronunciation in the default format.
    # @param customization_id [String] The customization ID (GUID) of a custom voice model for which the pronunciation is
    #   to be returned. The language of a specified custom model must match the language
    #   of the specified voice. If the word is not defined in the specified custom model,
    #   the service returns the default translation for the custom model's language. You
    #   must make the request with service credentials created for the instance of the
    #   service that owns the custom model. Omit the parameter to see the translation for
    #   the specified voice with no customization.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def get_pronunciation(text:, voice: nil, format: nil, customization_id: nil)
      raise ArgumentError.new("text must be provided") if text.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "get_pronunciation")
      headers.merge!(sdk_headers)

      params = {
        "text" => text,
        "voice" => voice,
        "format" => format,
        "customization_id" => customization_id
      }

      method_url = "/v1/pronunciation"

      response = request(
        method: "GET",
        url: method_url,
        headers: headers,
        params: params,
        accept_json: true
      )
      response
    end
    #########################
    # Custom models
    #########################

    ##
    # @!method create_voice_model(name:, language: nil, description: nil)
    # Create a custom model.
    # Creates a new empty custom voice model. You must specify a name for the new custom
    #   model. You can optionally specify the language and a description for the new
    #   model. The model is owned by the instance of the service whose credentials are
    #   used to create it.
    #
    #   **Note:** This method is currently a beta release.
    #
    #   **See also:** [Creating a custom
    #   model](https://cloud.ibm.com/docs/services/text-to-speech/custom-models.html#cuModelsCreate).
    # @param name [String] The name of the new custom voice model.
    # @param language [String] The language of the new custom voice model. Omit the parameter to use the the
    #   default language, `en-US`.
    # @param description [String] A description of the new custom voice model. Specifying a description is
    #   recommended.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def create_voice_model(name:, language: nil, description: nil)
      raise ArgumentError.new("name must be provided") if name.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "create_voice_model")
      headers.merge!(sdk_headers)

      data = {
        "name" => name,
        "language" => language,
        "description" => description
      }

      method_url = "/v1/customizations"

      response = request(
        method: "POST",
        url: method_url,
        headers: headers,
        json: data,
        accept_json: true
      )
      response
    end

    ##
    # @!method delete_voice_model(customization_id:)
    # Delete a custom model.
    # Deletes the specified custom voice model. You must use credentials for the
    #   instance of the service that owns a model to delete it.
    #
    #   **Note:** This method is currently a beta release.
    #
    #   **See also:** [Deleting a custom
    #   model](https://cloud.ibm.com/docs/services/text-to-speech/custom-models.html#cuModelsDelete).
    # @param customization_id [String] The customization ID (GUID) of the custom voice model. You must make the request
    #   with service credentials created for the instance of the service that owns the
    #   custom model.
    # @return [nil]
    def delete_voice_model(customization_id:)
      raise ArgumentError.new("customization_id must be provided") if customization_id.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "delete_voice_model")
      headers.merge!(sdk_headers)

      method_url = "/v1/customizations/%s" % [ERB::Util.url_encode(customization_id)]

      request(
        method: "DELETE",
        url: method_url,
        headers: headers,
        accept_json: false
      )
      nil
    end

    ##
    # @!method get_voice_model(customization_id:)
    # Get a custom model.
    # Gets all information about a specified custom voice model. In addition to metadata
    #   such as the name and description of the voice model, the output includes the words
    #   and their translations as defined in the model. To see just the metadata for a
    #   voice model, use the **List custom models** method.
    #
    #   **Note:** This method is currently a beta release.
    #
    #   **See also:** [Querying a custom
    #   model](https://cloud.ibm.com/docs/services/text-to-speech/custom-models.html#cuModelsQuery).
    # @param customization_id [String] The customization ID (GUID) of the custom voice model. You must make the request
    #   with service credentials created for the instance of the service that owns the
    #   custom model.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def get_voice_model(customization_id:)
      raise ArgumentError.new("customization_id must be provided") if customization_id.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "get_voice_model")
      headers.merge!(sdk_headers)

      method_url = "/v1/customizations/%s" % [ERB::Util.url_encode(customization_id)]

      response = request(
        method: "GET",
        url: method_url,
        headers: headers,
        accept_json: true
      )
      response
    end

    ##
    # @!method list_voice_models(language: nil)
    # List custom models.
    # Lists metadata such as the name and description for all custom voice models that
    #   are owned by an instance of the service. Specify a language to list the voice
    #   models for that language only. To see the words in addition to the metadata for a
    #   specific voice model, use the **List a custom model** method. You must use
    #   credentials for the instance of the service that owns a model to list information
    #   about it.
    #
    #   **Note:** This method is currently a beta release.
    #
    #   **See also:** [Querying all custom
    #   models](https://cloud.ibm.com/docs/services/text-to-speech/custom-models.html#cuModelsQueryAll).
    # @param language [String] The language for which custom voice models that are owned by the requesting
    #   service credentials are to be returned. Omit the parameter to see all custom voice
    #   models that are owned by the requester.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def list_voice_models(language: nil)
      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "list_voice_models")
      headers.merge!(sdk_headers)

      params = {
        "language" => language
      }

      method_url = "/v1/customizations"

      response = request(
        method: "GET",
        url: method_url,
        headers: headers,
        params: params,
        accept_json: true
      )
      response
    end

    ##
    # @!method update_voice_model(customization_id:, name: nil, description: nil, words: nil)
    # Update a custom model.
    # Updates information for the specified custom voice model. You can update metadata
    #   such as the name and description of the voice model. You can also update the words
    #   in the model and their translations. Adding a new translation for a word that
    #   already exists in a custom model overwrites the word's existing translation. A
    #   custom model can contain no more than 20,000 entries. You must use credentials for
    #   the instance of the service that owns a model to update it.
    #
    #   You can define sounds-like or phonetic translations for words. A sounds-like
    #   translation consists of one or more words that, when combined, sound like the
    #   word. Phonetic translations are based on the SSML phoneme format for representing
    #   a word. You can specify them in standard International Phonetic Alphabet (IPA)
    #   representation
    #
    #     <code><phoneme alphabet=\"ipa\"
    #   ph=\"təmˈɑto\"></phoneme></code>
    #
    #     or in the proprietary IBM Symbolic Phonetic Representation (SPR)
    #
    #     <code><phoneme alphabet=\"ibm\"
    #   ph=\"1gAstroEntxrYFXs\"></phoneme></code>
    #
    #   **Note:** This method is currently a beta release.
    #
    #   **See also:**
    #   * [Updating a custom
    #   model](https://cloud.ibm.com/docs/services/text-to-speech/custom-models.html#cuModelsUpdate)
    #   * [Adding words to a Japanese custom
    #   model](https://cloud.ibm.com/docs/services/text-to-speech/custom-entries.html#cuJapaneseAdd)
    #   * [Understanding
    #   customization](https://cloud.ibm.com/docs/services/text-to-speech/custom-intro.html).
    # @param customization_id [String] The customization ID (GUID) of the custom voice model. You must make the request
    #   with service credentials created for the instance of the service that owns the
    #   custom model.
    # @param name [String] A new name for the custom voice model.
    # @param description [String] A new description for the custom voice model.
    # @param words [Array[Word]] An array of `Word` objects that provides the words and their translations that are
    #   to be added or updated for the custom voice model. Pass an empty array to make no
    #   additions or updates.
    # @return [nil]
    def update_voice_model(customization_id:, name: nil, description: nil, words: nil)
      raise ArgumentError.new("customization_id must be provided") if customization_id.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "update_voice_model")
      headers.merge!(sdk_headers)

      data = {
        "name" => name,
        "description" => description,
        "words" => words
      }

      method_url = "/v1/customizations/%s" % [ERB::Util.url_encode(customization_id)]

      request(
        method: "POST",
        url: method_url,
        headers: headers,
        json: data,
        accept_json: true
      )
      nil
    end
    #########################
    # Custom words
    #########################

    ##
    # @!method add_word(customization_id:, word:, translation:, part_of_speech: nil)
    # Add a custom word.
    # Adds a single word and its translation to the specified custom voice model. Adding
    #   a new translation for a word that already exists in a custom model overwrites the
    #   word's existing translation. A custom model can contain no more than 20,000
    #   entries. You must use credentials for the instance of the service that owns a
    #   model to add a word to it.
    #
    #   You can define sounds-like or phonetic translations for words. A sounds-like
    #   translation consists of one or more words that, when combined, sound like the
    #   word. Phonetic translations are based on the SSML phoneme format for representing
    #   a word. You can specify them in standard International Phonetic Alphabet (IPA)
    #   representation
    #
    #     <code><phoneme alphabet=\"ipa\"
    #   ph=\"təmˈɑto\"></phoneme></code>
    #
    #     or in the proprietary IBM Symbolic Phonetic Representation (SPR)
    #
    #     <code><phoneme alphabet=\"ibm\"
    #   ph=\"1gAstroEntxrYFXs\"></phoneme></code>
    #
    #   **Note:** This method is currently a beta release.
    #
    #   **See also:**
    #   * [Adding a single word to a custom
    #   model](https://cloud.ibm.com/docs/services/text-to-speech/custom-entries.html#cuWordAdd)
    #   * [Adding words to a Japanese custom
    #   model](https://cloud.ibm.com/docs/services/text-to-speech/custom-entries.html#cuJapaneseAdd)
    #   * [Understanding
    #   customization](https://cloud.ibm.com/docs/services/text-to-speech/custom-intro.html).
    # @param customization_id [String] The customization ID (GUID) of the custom voice model. You must make the request
    #   with service credentials created for the instance of the service that owns the
    #   custom model.
    # @param word [String] The word that is to be added or updated for the custom voice model.
    # @param translation [String] The phonetic or sounds-like translation for the word. A phonetic translation is
    #   based on the SSML format for representing the phonetic string of a word either as
    #   an IPA translation or as an IBM SPR translation. A sounds-like is one or more
    #   words that, when combined, sound like the word.
    # @param part_of_speech [String] **Japanese only.** The part of speech for the word. The service uses the value to
    #   produce the correct intonation for the word. You can create only a single entry,
    #   with or without a single part of speech, for any word; you cannot create multiple
    #   entries with different parts of speech for the same word. For more information,
    #   see [Working with Japanese
    #   entries](https://cloud.ibm.com/docs/services/text-to-speech/custom-rules.html#jaNotes).
    # @return [nil]
    def add_word(customization_id:, word:, translation:, part_of_speech: nil)
      raise ArgumentError.new("customization_id must be provided") if customization_id.nil?

      raise ArgumentError.new("word must be provided") if word.nil?

      raise ArgumentError.new("translation must be provided") if translation.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "add_word")
      headers.merge!(sdk_headers)

      data = {
        "translation" => translation,
        "part_of_speech" => part_of_speech
      }

      method_url = "/v1/customizations/%s/words/%s" % [ERB::Util.url_encode(customization_id), ERB::Util.url_encode(word)]

      request(
        method: "PUT",
        url: method_url,
        headers: headers,
        json: data,
        accept_json: false
      )
      nil
    end

    ##
    # @!method add_words(customization_id:, words:)
    # Add custom words.
    # Adds one or more words and their translations to the specified custom voice model.
    #   Adding a new translation for a word that already exists in a custom model
    #   overwrites the word's existing translation. A custom model can contain no more
    #   than 20,000 entries. You must use credentials for the instance of the service that
    #   owns a model to add words to it.
    #
    #   You can define sounds-like or phonetic translations for words. A sounds-like
    #   translation consists of one or more words that, when combined, sound like the
    #   word. Phonetic translations are based on the SSML phoneme format for representing
    #   a word. You can specify them in standard International Phonetic Alphabet (IPA)
    #   representation
    #
    #     <code><phoneme alphabet=\"ipa\"
    #   ph=\"təmˈɑto\"></phoneme></code>
    #
    #     or in the proprietary IBM Symbolic Phonetic Representation (SPR)
    #
    #     <code><phoneme alphabet=\"ibm\"
    #   ph=\"1gAstroEntxrYFXs\"></phoneme></code>
    #
    #   **Note:** This method is currently a beta release.
    #
    #   **See also:**
    #   * [Adding multiple words to a custom
    #   model](https://cloud.ibm.com/docs/services/text-to-speech/custom-entries.html#cuWordsAdd)
    #   * [Adding words to a Japanese custom
    #   model](https://cloud.ibm.com/docs/services/text-to-speech/custom-entries.html#cuJapaneseAdd)
    #   * [Understanding
    #   customization](https://cloud.ibm.com/docs/services/text-to-speech/custom-intro.html).
    # @param customization_id [String] The customization ID (GUID) of the custom voice model. You must make the request
    #   with service credentials created for the instance of the service that owns the
    #   custom model.
    # @param words [Array[Word]] The **Add custom words** method accepts an array of `Word` objects. Each object
    #   provides a word that is to be added or updated for the custom voice model and the
    #   word's translation.
    #
    #   The **List custom words** method returns an array of `Word` objects. Each object
    #   shows a word and its translation from the custom voice model. The words are listed
    #   in alphabetical order, with uppercase letters listed before lowercase letters. The
    #   array is empty if the custom model contains no words.
    # @return [nil]
    def add_words(customization_id:, words:)
      raise ArgumentError.new("customization_id must be provided") if customization_id.nil?

      raise ArgumentError.new("words must be provided") if words.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "add_words")
      headers.merge!(sdk_headers)

      data = {
        "words" => words
      }

      method_url = "/v1/customizations/%s/words" % [ERB::Util.url_encode(customization_id)]

      request(
        method: "POST",
        url: method_url,
        headers: headers,
        json: data,
        accept_json: true
      )
      nil
    end

    ##
    # @!method delete_word(customization_id:, word:)
    # Delete a custom word.
    # Deletes a single word from the specified custom voice model. You must use
    #   credentials for the instance of the service that owns a model to delete its words.
    #
    #
    #   **Note:** This method is currently a beta release.
    #
    #   **See also:** [Deleting a word from a custom
    #   model](https://cloud.ibm.com/docs/services/text-to-speech/custom-entries.html#cuWordDelete).
    # @param customization_id [String] The customization ID (GUID) of the custom voice model. You must make the request
    #   with service credentials created for the instance of the service that owns the
    #   custom model.
    # @param word [String] The word that is to be deleted from the custom voice model.
    # @return [nil]
    def delete_word(customization_id:, word:)
      raise ArgumentError.new("customization_id must be provided") if customization_id.nil?

      raise ArgumentError.new("word must be provided") if word.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "delete_word")
      headers.merge!(sdk_headers)

      method_url = "/v1/customizations/%s/words/%s" % [ERB::Util.url_encode(customization_id), ERB::Util.url_encode(word)]

      request(
        method: "DELETE",
        url: method_url,
        headers: headers,
        accept_json: false
      )
      nil
    end

    ##
    # @!method get_word(customization_id:, word:)
    # Get a custom word.
    # Gets the translation for a single word from the specified custom model. The output
    #   shows the translation as it is defined in the model. You must use credentials for
    #   the instance of the service that owns a model to list its words.
    #
    #   **Note:** This method is currently a beta release.
    #
    #   **See also:** [Querying a single word from a custom
    #   model](https://cloud.ibm.com/docs/services/text-to-speech/custom-entries.html#cuWordQueryModel).
    # @param customization_id [String] The customization ID (GUID) of the custom voice model. You must make the request
    #   with service credentials created for the instance of the service that owns the
    #   custom model.
    # @param word [String] The word that is to be queried from the custom voice model.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def get_word(customization_id:, word:)
      raise ArgumentError.new("customization_id must be provided") if customization_id.nil?

      raise ArgumentError.new("word must be provided") if word.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "get_word")
      headers.merge!(sdk_headers)

      method_url = "/v1/customizations/%s/words/%s" % [ERB::Util.url_encode(customization_id), ERB::Util.url_encode(word)]

      response = request(
        method: "GET",
        url: method_url,
        headers: headers,
        accept_json: true
      )
      response
    end

    ##
    # @!method list_words(customization_id:)
    # List custom words.
    # Lists all of the words and their translations for the specified custom voice
    #   model. The output shows the translations as they are defined in the model. You
    #   must use credentials for the instance of the service that owns a model to list its
    #   words.
    #
    #   **Note:** This method is currently a beta release.
    #
    #   **See also:** [Querying all words from a custom
    #   model](https://cloud.ibm.com/docs/services/text-to-speech/custom-entries.html#cuWordsQueryModel).
    # @param customization_id [String] The customization ID (GUID) of the custom voice model. You must make the request
    #   with service credentials created for the instance of the service that owns the
    #   custom model.
    # @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.
    def list_words(customization_id:)
      raise ArgumentError.new("customization_id must be provided") if customization_id.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "list_words")
      headers.merge!(sdk_headers)

      method_url = "/v1/customizations/%s/words" % [ERB::Util.url_encode(customization_id)]

      response = request(
        method: "GET",
        url: method_url,
        headers: headers,
        accept_json: true
      )
      response
    end
    #########################
    # User data
    #########################

    ##
    # @!method delete_user_data(customer_id:)
    # Delete labeled data.
    # Deletes all data that is associated with a specified customer ID. The method
    #   deletes all data for the customer ID, regardless of the method by which the
    #   information was added. The method has no effect if no data is associated with the
    #   customer ID. You must issue the request with credentials for the same instance of
    #   the service that was used to associate the customer ID with the data.
    #
    #   You associate a customer ID with data by passing the `X-Watson-Metadata` header
    #   with a request that passes the data.
    #
    #   **See also:** [Information
    #   security](https://cloud.ibm.com/docs/services/text-to-speech/information-security.html).
    # @param customer_id [String] The customer ID for which all data is to be deleted.
    # @return [nil]
    def delete_user_data(customer_id:)
      raise ArgumentError.new("customer_id must be provided") if customer_id.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("text_to_speech", "V1", "delete_user_data")
      headers.merge!(sdk_headers)

      params = {
        "customer_id" => customer_id
      }

      method_url = "/v1/user_data"

      request(
        method: "DELETE",
        url: method_url,
        headers: headers,
        params: params,
        accept_json: false
      )
      nil
    end
  end
end