-- +goose Up
-- +goose StatementBegin

CREATE OR REPLACE FUNCTION teldrive.split_path(path text, OUT parent text, OUT base text) AS $$
BEGIN
    IF path = '/' THEN
        parent := '/';
        base := NULL;
        RETURN;
    END IF;

    IF left(path, 1) <> '/' THEN
        path := '/' || path;
    END IF;

    IF right(path, 1) = '/' THEN
        path := left(path, length(path) - 1);
    END IF;

    parent := left(path, length(path) - position('/' in reverse(path)));
    base := right(path, position('/' in reverse(path)) - 1);
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION teldrive.update_folder(
  folder_id TEXT,
  new_name TEXT,
  new_path TEXT DEFAULT NULL
) RETURNS SETOF teldrive.files
LANGUAGE plpgsql
AS $$
DECLARE
  folder RECORD;
  path_items TEXT[];
BEGIN
  IF new_path IS NULL THEN
      SELECT
          *
      INTO
          folder
      FROM
          teldrive.files
      WHERE
          id = folder_id;
      
      path_items := string_to_array(folder.path, '/');
      
      path_items[array_length(path_items, 1)] := new_name;
      
      new_path := array_to_string(path_items, '/');
  END IF;
  
  UPDATE
      teldrive.files
  SET
      path = new_path,
      name = new_name
  WHERE
      id = folder_id;
  
  FOR folder IN
      SELECT
          *
      FROM
          teldrive.files
      WHERE
          type = 'folder'
          AND parent_id = folder_id
  LOOP
     perform from teldrive.update_folder(
          folder.id,
          folder.name,
          concat(new_path, '/', folder.name)
      );
  END LOOP;
 
  RETURN QUERY
  SELECT
      *
  FROM
      teldrive.files
  WHERE
      id = folder_id;
END;
$$;

CREATE OR REPLACE FUNCTION teldrive.move_directory(src text, dest text,user_id bigint) RETURNS VOID AS $$
DECLARE
    src_parent TEXT;
    src_base TEXT;
    dest_parent TEXT;
    dest_base TEXT;
    dest_id text;
    src_id text;
BEGIN
	
    IF NOT EXISTS (SELECT 1 FROM teldrive.files WHERE path = src) THEN
        RAISE EXCEPTION 'source directory not found';
    END IF;
   
    IF EXISTS (SELECT 1 FROM teldrive.files WHERE path = dest) THEN
        RAISE EXCEPTION 'destination directory exists';
    END IF;
   
    SELECT parent, base INTO src_parent,src_base FROM teldrive.split_path(src);
   
    SELECT parent, base INTO dest_parent, dest_base FROM teldrive.split_path(dest);
   
    IF src_parent != dest_parent then
      select id into dest_id from teldrive.create_directories(user_id,dest);
      update teldrive.files set parent_id = dest_id where parent_id = (select id from teldrive.files where path = src) and id != dest_id;
      
      IF POSITION(CONCAT(src,'/') IN dest) = 0 then
         delete from teldrive.files where path = src;
      END IF;
     
    END IF;

    IF src_base != dest_base and src_parent = dest_parent then
       select id into src_id from teldrive.files where path = src;
       perform from teldrive.update_folder(src_id,dest_base);
    END IF;

END;
$$ LANGUAGE plpgsql;

-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
drop function if exists teldrive.split_path;
drop function if exists teldrive.update_folder;
drop function if exists teldrive.move_directory;
-- +goose StatementEnd
