--
-- workflow_case__finished_p/2
--
create or replace function workflow_case__finished_p(
  integer,
  integer
) returns bool as $$

declare
  finished_p__case_id                alias for $1;  
  finished_p__journal_id             alias for $2;  
  v_case_state                       varchar;
  v_token_id                         integer;
  v_num_rows                         integer;
  v_journal_id                       integer;
begin
        select state into v_case_state 
        from   wf_cases 
        where  case_id = finished_p__case_id;

        if v_case_state = 'finished' then
            return 't';
        else
            /* Let us see if the case is actually finished, but just not marked so */
            select case when count(*) = 0 then 0 else 1 end into v_num_rows
            from   wf_tokens
            where  case_id = finished_p__case_id
            and    place_key = 'end';
    
            if v_num_rows = 0 then 
                return 'f';
            else
                /* There is a token in the end place.
                 * Count the total integer of tokens to make sure the wf is well-constructed.
                 */
    
                select case when count(*) = 0 then 0
                            when count(*) = 1 then 1 
                                              else 2 
                        end into v_num_rows
                from   wf_tokens
                where  case_id = finished_p__case_id
                and    state in ('free', 'locked');
    
                if v_num_rows > 1 then 
                    raise EXCEPTION '-20000: The workflow net is misconstructed: Some parallel executions have not finished.';
                end if;
    
                /* Consume that token */
                select token_id into v_token_id
                from   wf_tokens
                where  case_id = finished_p__case_id
                and    state in ('free', 'locked');

                PERFORM workflow_case__consume_token (
                    finished_p__case_id,
                    'end',
                    finished_p__journal_id,
                    null
                );

                update wf_cases 
                set    state = 'finished' 
                where  case_id = finished_p__case_id;

                /* Add an extra entry to the journal */
                v_journal_id := journal_entry__new (
                    null,
                    finished_p__case_id,
                    'case finish',
                    'Case finished',
                    now(),
                    null,
                    null,
                    null
                );

                return 't';
            end if;
        end if;
     
end;$$ language plpgsql;