#
# Aura Engine (https://gitlab.servus.at/aura/engine)
#
# Copyright (C) 2017-2020 - The Aura Engine Team.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

#
# Namespace: aura_engine
#

# Get state of the inputs/outputs as JSON
server.register(
  namespace="aura_engine",
  description=
    "Get status info (uptime and fallback state)",
  usage="status",
  "status",
  fun (s) ->
    begin
      ignore(s)
      uptime = list.nth(server.execute("uptime"), 0)
      json_data = json()
      json_data.add("uptime", uptime)
      json_data.add("is_fallback", engine_state.is_fallback())
      json.stringify(json_data)
    end
)

# Updates engine config
server.register(
  namespace="aura_engine",
  description=
    "Update the engine configuration",
  usage=
    "update_config { \"fallback_show_id\": \"-1\", \"fallback_show_name\": \
     \"Station Fallback\" }",
  "update_config",
  fun (s) ->
    begin
      log(
        "Received JSON to update config: #{s}"
      )
      let json.parse (data :
        {fallback_show_id: int, fallback_show_name: string}
      ) = s

      fallback_show_id := "#{data.fallback_show_id}"
      log(
        "Set Fallback Show ID to '#{fallback_show_id()}'"
      )
      fallback_show_name := data.fallback_show_name
      log(
        "Set Fallback Show Name to '#{fallback_show_name()}'"
      )
      "OK"
    end
)

# Get version
server.register(
  namespace="aura_engine",
  description=
    "Return the version of Engine Core and Liquidsoap",
  usage="version",
  "version",
  fun (s) ->
    begin
      ignore(s)
      json_data = json()
      json_data.add("core", engine_version)
      json_data.add("liquidsoap", liquidsoap.version)
      json.stringify(json_data)
    end
)

# Shutdown server
server.register(
  namespace="aura_engine",
  description=
    "Shutdown play-out server",
  usage="stop",
  "stop",
  fun (s) ->
    begin
      ignore(s)
      shutdown(code=0)
      "OK"
    end
)

#
# Namespace: mixer
#

# Get connection state of outgoing streams #TODO refactor
server.register(
  namespace="mixer",
  description=
    "Return all active outputs",
  usage="outputs",
  "outputs",
  fun (s) ->
    begin
      ignore(s)
      log(
        "executing: mixer.outputs"
      )

      so = []
      so =
        s0_enable
        ? list.add(("out_line_0", ("connected", "#{s0_connected()}")), so) : so
      # so =
      #   s1_enable
      #   ? list.add(("out_line_1", ("connected", "#{s1_connected()}")), so) : so
      # so =
      #   s2_enable
      #   ? list.add(("out_line_2", ("connected", "#{s2_connected()}")), so) : so
      # so =
      #   s3_enable
      #   ? list.add(("out_line_3", ("connected", "#{s3_connected()}")), so) : so
      # so =
      #   s4_enable
      #   ? list.add(("out_line_4", ("connected", "#{s4_connected()}")), so) : so

      lo = []
      lo = a0_out != '' ? list.add("out_line_0", lo) : lo
      lo = a1_out != '' ? list.add("out_line_1", lo) : lo
      lo = a2_out != '' ? list.add("out_line_2", lo) : lo
      lo = a3_out != '' ? list.add("out_line_3", lo) : lo
      lo = a4_out != '' ? list.add("out_line_4", lo) : lo

      json_data = json()
      json_data.add("line", lo)
      json_data.add("stream", so)
      json.stringify(json_data)
    end
)

# Activate a source by selecting it and setting the volume to 100 (or vice versa)
server.register(
  namespace="mixer",
  description=
    "Select a source and set the volume to 100",
  usage=
    "activate <source number> <true|false>",
  "activate",
  fun (p) ->
    begin
      params =
        string.split(
          separator=
            " ",
          p
        )
      if
        list.length(params) < 2
      then
        print(p)
        "Usage: mixer.activate <source nb> <true|false>"
      else
        source_number = list.nth(default="0", params, 0)
        source_enable = list.nth(default="false", params, 1)

        if
          source_enable == "true"
        then
          r =
            server.execute(
              "mixer.select #{source_number} true"
            )
          print(r)
          r =
            server.execute(
              "mixer.volume #{source_number} 1"
            )
          print(r)
        else
          r =
            server.execute(
              "mixer.volume #{source_number} 0"
            )
          print(r)
          r =
            server.execute(
              "mixer.select #{source_number} false"
            )
          print(r)
        end
        "OK"
      end
    end
)

#
# Namespace: misc #TODO: refactor
#

def fadeTo(source_number) =
  if
    source_number == ""
  then
    print(source_number)
    "Usage: mixer.fadeto <source nb> #{source_number}"
  else
    r =
      server.execute(
        "mixer.select #{source_number} true"
      )
    print(r)
    "OK"
  end
end

# enable fadeTo for the mixer
server.register(
  namespace="mixer",
  description=
    "is fading from one mixer input to another",
  usage=
    "fadeto <source number>",
  "fadeto",
  fadeTo
)

def icy_update(v) =
  # Parse the argument
  l = string.split(separator=",", v)
  def split(l, v) =
    v = string.split(separator="=", v)
    if
      list.length(v) >= 2
    then
      list.append(l, [(list.nth(v, 0, default=""), list.nth(v, 1, default=""))])
    else
      l
    end
  end
  meta = list.fold(split, [], l)

  # Update metadata
  if
    s0_enable == true
  then
    icy.update_metadata(
      mount=s0_mount,
      user=s0_user,
      password=s0_pass,
      host=s0_host,
      port=s0_port,
      meta
    )
  end

  #   if
  #     s1_enable == true
  #   then
  #     icy.update_metadata(
  #       mount=s1_mount,
  #       user=s1_user,
  #       password=s1_pass,
  #       host=s1_host,
  #       port=s1_port,
  #       meta
  #     )
  #   end

  #   if
  #     s2_enable == true
  #   then
  #     icy.update_metadata(
  #       mount=s2_mount,
  #       user=s2_user,
  #       password=s2_pass,
  #       host=s2_host,
  #       port=s2_port,
  #       meta
  #     )
  #   end

  #   if
  #     s3_enable == true
  #   then
  #     icy.update_metadata(
  #       mount=s3_mount,
  #       user=s3_user,
  #       password=s3_pass,
  #       host=s3_host,
  #       port=s3_port,
  #       meta
  #     )
  #   end

  #   if
  #     s4_enable == true
  #   then
  #     icy.update_metadata(
  #       mount=s4_mount,
  #       user=s4_user,
  #       password=s4_pass,
  #       host=s4_host,
  #       port=s4_port,
  #       meta
  #     )
  #   end

  "OK"
end

server.register(
  "update",
  namespace="metadata",
  description=
    "Update metadata",
  usage=
    "update title=foo,album=bar, ...",
  icy_update
)