local Rx = require 'Rx'

local AnonymousObservable = Rx.AnonymousObservable
local disposableCreate = Rx.Disposable.create

--------------------------------------------------------------------------------

return function(self, action)

    if type(action) ~= 'function' then
        error("Rx.Observable:finally: action must be a function", 2)
    end

    return AnonymousObservable(function(observer)

        local function handleEarlyFailure(success, ...)

            if not success then
                action()
                local errMsg = ...
                error(errMsg)
            end
            return ...

        end

        local subscription = handleEarlyFailure(pcall(function()
            return self:subscribe(observer)
        end))

        return disposableCreate(function()

            local function callActionAndRethrow(success, err)
                action()
                if not success then
                    error(err)
                end
            end

            callActionAndRethrow(pcall(function()
                subscription:dispose()
            end))

        end)

    end, self)

end
