#
# 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 connection state of outgoing streams #TODO refactor
server.register(namespace="aura_engine",
    description="Returns if outgoing streams are connected",
    usage="out_streams_connected",
    "out_streams_connected",
    fun (s) -> begin
        ignore(s)
        log("executing: aura_engine.out_streams_connected")
        "0:#{!s0_connected}, 1:#{!s1_connected}, 2:#{!s2_connected}, 3:#{!s3_connected}, 4:#{!s4_connected}"
    end
)

# Get state of the inputs/outputs as JSON
server.register(namespace = "aura_engine",
    description="Returns enabled line-in, line-out and connected outgoing streams",
    usage="status",
    "status",
    fun(s) -> begin
        ignore(s)
        log("executing: aura_engine.status")

        json_streams = {
            stream_0 = { enabled = "#{s0_enable}", connected = "#{!s0_connected}" },
            stream_1 = { enabled = "#{s1_enable}", connected = "#{!s1_connected}" },
            stream_2 = { enabled = "#{s2_enable}", connected = "#{!s2_connected}" },
            stream_3 = { enabled = "#{s3_enable}", connected = "#{!s3_connected}" },
            stream_4 = { enabled = "#{s4_enable}", connected = "#{!s4_connected}" }
        }
        json_linein = {
            linein_0 = { enabled = "#{a0_in != ''}" },
            linein_1 = { enabled = "#{a1_in != ''}" },
            linein_2 = { enabled = "#{a2_in != ''}" },
            linein_3 = { enabled = "#{a3_in != ''}" },
            linein_4 = { enabled = "#{a4_in != ''}" }
        }
        json_lineout = {
            lineout_0 = { enabled = "#{a0_out != ''}" },
            lineout_1 = { enabled = "#{a1_out != ''}" },
            lineout_2 = { enabled = "#{a2_out != ''}" },
            lineout_3 = { enabled = "#{a3_out != ''}" },
            lineout_4 = { enabled = "#{a4_out != ''}" }
        }

        json_data = json()
        json_data.add("streams", json_streams)
        json_data.add("linein", json_linein)
        json_data.add("lineout", json_lineout)
        json.stringify(json_data)
    end
)



# Updates engine config
server.register(namespace="aura_engine",
    description="Updates 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="Returns the version of Engine Core",
    usage="version",
    "version",
    fun (s) -> begin
        ignore(s)
        engine_version
    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
#


# 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
            "Done!"
        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)