USE [master]
GO

DROP PROCEDURE IF EXISTS [dbo].[sp_RestaurarBackup]
GO

CREATE PROCEDURE [dbo].[sp_RestaurarBackup]
    @Arquivo   NVARCHAR(500) = NULL,
    @Tipo      CHAR(1)       = 'F'   -- 'F' = FULL | 'D' = DIFERENCIAL
AS
BEGIN
    SET NOCOUNT ON;

    -- =============================================
    -- Se não informar arquivo, lista os disponíveis
    -- =============================================
    IF @Arquivo IS NULL
    BEGIN
        PRINT '>>> Backups disponíveis no histórico:';

        SELECT 
            ROW_NUMBER() OVER (ORDER BY bs.backup_finish_date DESC) AS N,
            CASE bs.type 
                WHEN 'D' THEN 'FULL'
                WHEN 'I' THEN 'DIFERENCIAL'
            END AS Tipo,
            bmf.physical_device_name AS Arquivo,
            bs.backup_start_date     AS Inicio,
            bs.backup_finish_date    AS Fim,
            CAST(bs.backup_size / 1024.0 / 1024.0 AS DECIMAL(10,2)) AS TamanhoMB
        FROM msdb.dbo.backupset bs
        JOIN msdb.dbo.backupmediafamily bmf 
            ON bs.media_set_id = bmf.media_set_id
        WHERE bs.database_name = 'Levelcode-LevelOS'
        ORDER BY bs.backup_finish_date DESC;

        PRINT '>>> Copie o caminho do arquivo desejado e execute:';
        PRINT '>>> EXEC sp_RestaurarBackup @Arquivo = ''caminho_aqui'', @Tipo = ''F''';
        RETURN;
    END

    -- =============================================
    -- Verifica o arquivo com RESTORE HEADERONLY
    -- =============================================
    BEGIN TRY
        RESTORE HEADERONLY FROM DISK = @Arquivo;
    END TRY
    BEGIN CATCH
        RAISERROR('Arquivo não encontrado ou inválido: %s', 16, 1, @Arquivo);
        RETURN;
    END CATCH

    -- =============================================
    -- Coloca o banco em SINGLE_USER
    -- =============================================
    PRINT '>>> Preparando banco para restauração...';

    BEGIN TRY
        ALTER DATABASE [Levelcode-LevelOS] 
        SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    END TRY
    BEGIN CATCH
        PRINT '>>> Aviso: ' + ERROR_MESSAGE();
    END CATCH

    -- =============================================
    -- Restauração FULL
    -- =============================================
    IF @Tipo = 'F'
    BEGIN
        PRINT '>>> Restaurando FULL: ' + @Arquivo;

        RESTORE DATABASE [Levelcode-LevelOS]
        FROM DISK = @Arquivo
        WITH REPLACE,
             NORECOVERY,
             STATS = 10;

        ALTER DATABASE [Levelcode-LevelOS] SET MULTI_USER;

        PRINT '>>> FULL restaurado com sucesso!';
        PRINT '>>> Se tiver diferencial execute: EXEC sp_RestaurarBackup @Arquivo = ''caminho_diff'', @Tipo = ''D''';
        PRINT '>>> Se não tiver diferencial execute: RESTORE DATABASE [Levelcode-LevelOS] WITH RECOVERY;';
    END

    -- =============================================
    -- Restauração DIFERENCIAL
    -- =============================================
    IF @Tipo = 'D'
    BEGIN
        PRINT '>>> Aplicando DIFERENCIAL: ' + @Arquivo;

        RESTORE DATABASE [Levelcode-LevelOS]
        FROM DISK = @Arquivo
        WITH RECOVERY,
             STATS = 10;

        ALTER DATABASE [Levelcode-LevelOS] SET MULTI_USER;

        PRINT '>>> Banco restaurado e online!';
    END
END
GO

--Como usar --
-- 1. Lista os backups disponíveis
EXEC [master].[dbo].[sp_RestaurarBackup];

-- 2. Restaura apenas o FULL (sem diferencial)
EXEC [master].[dbo].[sp_RestaurarBackup] 
    @Arquivo = '/var/opt/mssql/backups/Levelcode-LevelOS_FULL_20260413_020000.bak',
    @Tipo    = 'F';

-- Finaliza o banco após o FULL sem diferencial
RESTORE DATABASE [Levelcode-LevelOS] WITH RECOVERY;

-- 3. Restaura FULL + DIFERENCIAL (sequência completa)
EXEC [master].[dbo].[sp_RestaurarBackup] 
    @Arquivo = '/var/opt/mssql/backups/Levelcode-LevelOS_FULL_20260413_020000.bak',
    @Tipo    = 'F';

EXEC [master].[dbo].[sp_RestaurarBackup] 
    @Arquivo = '/var/opt/mssql/backups/Levelcode-LevelOS_DIFF_20260413_080000.bak',
    @Tipo    = 'D';

EXEC [master].[dbo].[sp_RestaurarBackup] 
    @Arquivo = '/var/opt/mssql/backups/Levelcode-LevelOS_FULL_20260413_072013.bak',
    @Tipo    = 'F';