/*
 * Copyright 2021 Comcast Cable Communications Management, LLC
 *
 * 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.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

export module Settings {
    type LogLevel = "WARN" | "INFO" | "DEBUG" | "ERROR"
    function setLogLevel(logLevel: LogLevel): void
    function getLogLevel(): LogLevel     
}

export module Log {
    function info(...args: any[]): void
    function debug(...args: any[]): void
    function error(...args: any[]): void
    function warn(...args: any[]): void
}

export module Events {
    function listen(...args: any[]): Promise<number>
    function once(...args: any[]): Promise<number>
    function clear(...args: any[]): boolean
}

export module Player {


// Types

    /**
     * 
     */

type PlayerMediaSession = {
  mediaSessionId: string     // The id of media session that was started, when the content was loaded. This should be a new value on each load
}
    /**
     * 
     */

type PlayerLoadRequest = {
  playerId: string          // The id of the player instance to load the locator into
  locator: string           // A locator to the content to load
  metadata?: {
  }
  autoPlay?: boolean        // Start playing immediately on load without needing to call Player.play
}
    /**
     * 
     */

type PlayerRequest = {
  playerId: string      // The id of the player instance to play in
}
    /**
     * 
     */

type PlayerStatus = {
  mediaSessionId: string                                                                                                                                                                              // The id of media session that is currently loaded
  state: 'IDLE' | 'PENDING' | 'PLAYING' | 'BLOCKED' | 'FAILED'                                                                                                                                        // The state of the player
  blockedReason?: 'NO_NETWORK' | 'CONTENT_NOT_FOUND' | 'DRM_ERROR' | 'NOT_ENTITLED' | 'GEO_BLOCKED' | 'CHANNEL_NOT_SCANNED' | 'NO_SIGNAL' | 'TECHNICAL_FAULT' | 'CHANNEL_OFF_AIR' | 'PLAYER_FAILURE'  // The state of the player
}
    /**
     * 
     */

type PlayerProgress = {
  speed: number          // The playback speed as a multiplier
  startPosition: number  // The position that the media starts at in milliseconds
  position: number       // The current position in milliseconds
  endPosition: number    // The position that the media stops at in milliseconds
  liveSyncTime: string   // The time to sync to live
}
    /**
     * 
     */

type PlayerLoadProviderRequest = {
  correlationId: string             // An id to correlate the provider response with this request
  parameters: PlayerLoadRequest
}
    /**
     * 
     */

type PlayerProviderRequest = {
  correlationId: string         // An id to correlate the provider response with this request
  parameters: PlayerRequest
}

  /**
   * Tells listeners the current progress of a player
   * 
   * @param {string} playerId The id of the player the progress is for
   * @param {PlayerProgress} progress The progress
  */
  function provideProgress(playerId: string, progress: PlayerProgress): Promise<void>

  /**
   * Tells listeners the current status of a player
   * 
   * @param {string} playerId The id of the player the status is for
   * @param {PlayerStatus} status The status
  */
  function provideStatus(playerId: string, status: PlayerStatus): Promise<void>


    // Provider Interfaces

    interface ProviderSession {
        correlationId(): string        // Returns the correlation id of the current provider session
    }
    
    interface FocusableProviderSession extends ProviderSession {
        focus(): Promise<void>         // Requests that the provider app be moved into focus to prevent a user experience
    }
    
    interface BasePlayerProvider {
	load(parameters?: PlayerLoadRequest, session?: ProviderSession): Promise<PlayerMediaSession>
	play(parameters?: PlayerRequest, session?: ProviderSession): Promise<PlayerMediaSession>
	stop(parameters?: PlayerRequest, session?: ProviderSession): Promise<PlayerMediaSession>
	status(parameters?: PlayerRequest, session?: ProviderSession): Promise<PlayerStatus>
	progress(parameters?: PlayerRequest, session?: ProviderSession): Promise<PlayerProgress>
}


function provide(capability: 'xrn:firebolt:capability:player:base', provider: BasePlayerProvider | object): Promise<void>

}

export module BroadcastPlayer {


// Types

    /**
     * 
     */

type BroadcastPlayerInstance = {
  playerId: string                // The id of player which can be used to load media or control the player
  windowId: string                // The id of window which will render the media in, can be used to control on screen where the media is shown
}
    /**
     * 
     */

type BroadcastPlayerCreateRequest = {
}
    /**
     * 
     */

type BroadcastPlayerStatus = {
  locked: boolean               // Whether the current media has been locked
  frequency: number             // The signal frequency in hertz
  signalStrength: number        // The strength of the signal from 0-100
  signalQuality: number         // The quality of the signal from 0-100
}
    /**
     * 
     */

type PlayerRequest = {
  playerId: string      // The id of the player instance to play in
}
    /**
     * 
     */

type BroadcastPlayerCreateProviderRequest = {
  correlationId: string                        // An id to correlate the provider response with this request
  parameters: BroadcastPlayerCreateRequest
}
    /**
     * 
     */

type PlayerProviderRequest = {
  correlationId: string         // An id to correlate the provider response with this request
  parameters: PlayerRequest
}

  /**
   * Tells listeners the current broadcast status of a player
   * 
   * @param {string} playerId The id of the player the status is for
   * @param {BroadcastPlayerStatus} status The status
  */
  function provideStatus(playerId: string, status: BroadcastPlayerStatus): Promise<void>


    // Provider Interfaces

    interface ProviderSession {
        correlationId(): string        // Returns the correlation id of the current provider session
    }
    
    interface FocusableProviderSession extends ProviderSession {
        focus(): Promise<void>         // Requests that the provider app be moved into focus to prevent a user experience
    }
    
    interface BroadcastPlayerProvider {
	create(parameters?: BroadcastPlayerCreateRequest, session?: ProviderSession): Promise<BroadcastPlayerInstance>
	status(parameters?: PlayerRequest, session?: ProviderSession): Promise<BroadcastPlayerStatus>
}


function provide(capability: 'xrn:firebolt:capability:player:broadcast', provider: BroadcastPlayerProvider | object): Promise<void>

}
export module StreamingPlayer {


// Types

    /**
     * 
     */

type StreamingPlayerInstance = {
  playerId: string                // The id of player which can be used to load media or control the player
  windowId: string                // The id of window which will render the media in, can be used to control on screen where the media is shown
}
    /**
     * 
     */

type StreamingPlayerCreateRequest = {
}
    /**
     * 
     */

type StreamingPlayerCreateProviderRequest = {
  correlationId: string                        // An id to correlate the provider response with this request
  parameters: StreamingPlayerCreateRequest
}


    // Provider Interfaces

    interface ProviderSession {
        correlationId(): string        // Returns the correlation id of the current provider session
    }
    
    interface FocusableProviderSession extends ProviderSession {
        focus(): Promise<void>         // Requests that the provider app be moved into focus to prevent a user experience
    }
    
    interface CreateProvider {
	create(parameters?: StreamingPlayerCreateRequest, session?: ProviderSession): Promise<StreamingPlayerInstance>
}


function provide(capability: 'xrn:firebolt:capability:player:streaming', provider: CreateProvider | object): Promise<void>

}