-- Copyright (c) 2015 gutlib.com - All rights reserved. Terms are in gutlib.sql
-- You are NOT ALLOWED to modify and/or use this code without author permission

exec g.fn 'g.nest_str'
go
alter function g.nest_str (@arg nvarchar(max))
   returns nvarchar(max)
as begin
   if @arg is null return null

   declare
       @ret nvarchar(max)=''
      ,@i int = 0
      ,@mult varchar(4000)=''''
      ,@c varchar(1)
      ,@len int = len(@arg)

   while @len > 0 begin
      set @i = patindex('%[{}''"]%',@arg)
      if @i = 0 begin
         set @ret += @arg
         break
      end

      set @len -= @i-1
      set @ret += substring(@arg ,1 ,@i-1)
      set @c = substring(@arg ,@i ,1)
      set @arg = substring(@arg ,@i+1 ,@len)
      if @c = '{' begin
         set @ret += @mult
         set @mult += @mult
      end else if @c in ('''','"') begin
         set @ret += @mult
      end else if @c = '}' begin
         if len(@mult) = 1
            return cast('g.nest_str.err.1: Missing opening or extra closing curly brace.
               ' + @ret as int) -- forcing error in function
         set @mult = left(@mult ,len(@mult)/2)
         set @ret += @mult
      end
   end
   if len(@mult) != 1
      return cast('g.nest_str.err.2: Missing closing curly brace.
      ' + @ret as int) -- forcing error
   return @ret
end

go -- unit tests
if g.nest_str('{a}') != '''a'''
   RAISERROR ('g.nest_str.err.3' ,16 ,1)

if g.nest_str('''a''') != '''a'''
   RAISERROR ('g.nest_str.err.4' ,16 ,1)

begin try
   print g.nest_str('{')
   RAISERROR ('g.nest_str.err.5' ,16 ,1)
end try begin catch
   if error_message() not like '%g.nest_str.err.[2]:%'
      RAISERROR ('g.nest_str.err.6: Balancing curly braces' ,16 ,1)
end catch

begin try
   print g.nest_str('}')
   RAISERROR ('g.nest_str.err.7' ,16 ,1)
end try begin catch
   if error_message() not like '%g.nest_str.err.[1]:%'
      RAISERROR ('g.nest_str.err.8: Balancing curly braces' ,16 ,1)
end catch

if g.nest_str('
   for{a,b,c},{d,e,f},{
      for{1,2,3},{},{
         print {abc}
      }
   }') != '
   for''a,b,c'',''d,e,f'',''
      for''''1,2,3'''','''''''',''''
         print ''''''''abc''''''''
      ''''
   '''
   RAISERROR ('g.nest_str.err.9' ,16 ,1)

if g.nest_str('for{"a","b","c"}') != 'for''''''a'''',''''b'''',''''c'''''''
   RAISERROR ('g.nest_str.err.10' ,16 ,1)

if len(g.nest_str('')) != 0
   RAISERROR ('g.nest_str.err.11' ,16 ,1)

if g.nest_str(null) is not null
   RAISERROR ('g.nest_str.err.12' ,16 ,1)

if g.nest_str('a{"b","c",{d{e}f}"g"}h') != 'a''''''b'''',''''c'''',''''d''''''''e''''''''f''''''''g''''''h'
   RAISERROR ('g.nest_str.err.13' ,16 ,1)
