{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a8de14bc",
   "metadata": {},
   "source": [
    "# filoma — Quick interactive examples\n",
    "\n",
    "This notebook demonstrates key filoma capabilities and includes lightweight checks to see if it works in your environment.\n",
    "\n",
    "It covers: imports and version checks, probing a file and a directory, working with the `filoma.DataFrame` wrapper, using `probe_to_df`, a small image probe example, and saving a CSV export.\n",
    "\n",
    "Note: cells wrap operations in `try/except` so the notebook still runs if optional dependencies (e.g. `polars`, `numpy`, or image backends) are missing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1f1acab5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Basic environment and import checks\n",
    "from pathlib import Path\n",
    "\n",
    "import filoma\n",
    "from filoma import DataFrame\n",
    "\n",
    "\n",
    "def check_imports():\n",
    "    results = {}\n",
    "    try:\n",
    "        import filoma\n",
    "\n",
    "        results[\"filoma\"] = getattr(filoma, \"__version__\", \"unknown\")\n",
    "    except Exception as e:\n",
    "        results[\"filoma\"] = f\"IMPORT ERROR: {e}\"\n",
    "\n",
    "    for pkg in (\"polars\", \"numpy\", \"PIL\"):\n",
    "        try:\n",
    "            __import__(pkg if pkg != \"PIL\" else \"PIL.Image\")\n",
    "            results[pkg] = \"available\"\n",
    "        except Exception as e:\n",
    "            results[pkg] = f\"missing ({e})\"\n",
    "\n",
    "    # show where we are running the notebook from\n",
    "    results[\"cwd\"] = str(Path(\".\").resolve())\n",
    "    return results\n",
    "\n",
    "\n",
    "check_imports()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5492a20b",
   "metadata": {},
   "source": [
    "## 1) Quick probe: a single file and a directory\n",
    "\n",
    "Try probing a README or small file, then probe a lightweight sample directory from the repo's `tests/` tree."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "623b0d1e",
   "metadata": {},
   "outputs": [],
   "source": [
    "file_candidate = \"../README.md\"\n",
    "dir_candidate = \"../tests/\"\n",
    "\n",
    "print(\"probing file ->\", file_candidate)\n",
    "if file_candidate is not None:\n",
    "    try:\n",
    "        file_report = filoma.probe(file_candidate)\n",
    "        print(\"file probe result type:\", type(file_report))\n",
    "        try:\n",
    "            # many filoma dataclasses implement a nice repr or to-dict\n",
    "            print(file_report)\n",
    "        except Exception:\n",
    "            pass\n",
    "    except Exception as e:\n",
    "        print(\"file probe failed:\", e)\n",
    "else:\n",
    "    print(\"No small file found to probe in the repository root.\")\n",
    "\n",
    "print(\"probing directory ->\", dir_candidate)\n",
    "if dir_candidate is not None:\n",
    "    try:\n",
    "        dir_report = filoma.probe(dir_candidate, max_depth=2, threads=2)\n",
    "        print(\"directory probe returned an object of type:\", type(dir_report))\n",
    "        # If it exposes a to_df() method we can inspect a little\n",
    "        if hasattr(dir_report, \"to_df\"):\n",
    "            try:\n",
    "                dfw = dir_report.to_df()\n",
    "                print(\"to_df() -> wrapper type:\", type(dfw))\n",
    "            except Exception as e:\n",
    "                print(\"to_df() raised:\", e)\n",
    "    except Exception as e:\n",
    "        print(\"directory probe failed:\", e)\n",
    "else:\n",
    "    print(\"No small directory found to probe in tests/; adjust the path and re-run.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6762e273",
   "metadata": {},
   "source": [
    "## 2) Working with `filoma.DataFrame` wrapper\n",
    "\n",
    "Construct a `filoma.DataFrame` from a list of paths and run the convenience enrichers: `.add_path_components()`, `.add_file_stats_cols()`, and `.add_depth_col()`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "57537daa",
   "metadata": {},
   "outputs": [],
   "source": [
    "sample_paths = [p for p in (Path(\"../README.md\"), Path(\"../pyproject.toml\"), Path(\"../Cargo.toml\")) if p.exists()]\n",
    "if not sample_paths:\n",
    "    # fallback to a couple of files from tests if present\n",
    "    sample_paths = [p for p in (Path(\"../tests/test_basic_dataframe.py\"), Path(\"../tests/test_rust_comprehensive.py\")) if p.exists()]\n",
    "\n",
    "print(\"sample paths used:\", sample_paths)\n",
    "dfw = DataFrame(sample_paths)\n",
    "print(\"Initial wrapper and head:\")\n",
    "print(dfw.head(10))\n",
    "\n",
    "print(\"With path components:\")\n",
    "try:\n",
    "    df_components = dfw.add_path_components()\n",
    "    print(df_components.head(10))\n",
    "except Exception as e:\n",
    "    print(\"add_path_components failed:\", e)\n",
    "\n",
    "print(\"With file stats:\")\n",
    "try:\n",
    "    df_stats = dfw.add_file_stats_cols()\n",
    "    print(df_stats.head(10))\n",
    "except Exception as e:\n",
    "    print(\"add_file_stats_cols failed:\", e)\n",
    "\n",
    "print(\"Add depth column relative to repo root:\")\n",
    "try:\n",
    "    df_depth = dfw.add_depth_col(Path(\".\"))\n",
    "    print(df_depth.head(10))\n",
    "except Exception as e:\n",
    "    print(\"add_depth_col failed:\", e)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "73602797",
   "metadata": {},
   "source": [
    "## 3) Build a DataFrame from a directory using `probe_to_df`\n",
    "\n",
    "This uses filoma's convenience `probe_to_df` which will build a Polars DataFrame if `polars` is installed. We request a lightweight folder under `tests/` to keep runtime small."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "883738ea",
   "metadata": {},
   "outputs": [],
   "source": [
    "from filoma import probe_to_df\n",
    "\n",
    "dir_path = \"../tests\"\n",
    "if dir_path is None:\n",
    "    print(\"No test directory available for probe_to_df; skip this cell.\")\n",
    "else:\n",
    "    try:\n",
    "        pl_df = probe_to_df(dir_path, to_pandas=False, enrich=True, max_depth=2, threads=2)\n",
    "        print(\"probe_to_df returned a Polars DataFrame with shape:\", pl_df.shape)\n",
    "        # Show a small sample and a group_by_extension summary when available\n",
    "        try:\n",
    "            print(\"Sample rows:\")\n",
    "            print(pl_df.head(5))\n",
    "        except Exception:\n",
    "            pass\n",
    "        try:\n",
    "            print(\"Extension counts:\")\n",
    "            # wrap it in a DataFrame wrapper if needed\n",
    "            from filoma import DataFrame as DFWrap\n",
    "\n",
    "            wrapper = DFWrap(pl_df)\n",
    "            print(wrapper.group_by_extension().head(10))\n",
    "        except Exception as e:\n",
    "            print(\"group_by_extension failed:\", e)\n",
    "    except Exception as e:\n",
    "        print(\"probe_to_df failed:\", e)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4792a7e9",
   "metadata": {},
   "source": [
    "## 4) Image probing (in-memory)\n",
    "\n",
    "Create a small numpy array and pass it to `filoma.probe_image` to exercise the image path that accepts arrays. This avoids needing image files or heavy dependencies."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "01d15e2e",
   "metadata": {},
   "outputs": [],
   "source": [
    "try:\n",
    "    import numpy as np\n",
    "\n",
    "    arr = np.random.randn(16, 16)\n",
    "    img_report = filoma.probe_image(arr)\n",
    "    print(\"probe_image on numpy array returned type:\", type(img_report))\n",
    "    try:\n",
    "        print(img_report)\n",
    "    except Exception:\n",
    "        pass\n",
    "except Exception as e:\n",
    "    print(\"Skipping image probe; numpy unavailable or probe failed:\", e)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d521ed6e",
   "metadata": {},
   "source": [
    "## 5) Save a small CSV export (if `polars` is available)\n",
    "\n",
    "This cell attempts to save the `probe_to_df` result or our small DataFrame example to `/tmp/filoma_example.csv`. It prints a short verification sample."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "77b6aacb",
   "metadata": {},
   "outputs": [],
   "source": [
    "out_path = Path(\"/tmp/filoma_example.csv\")\n",
    "saved = False\n",
    "try:\n",
    "    if \"pl_df\" in globals():\n",
    "        # Try write via polars if present\n",
    "        try:\n",
    "            pl_df.write_csv(str(out_path))\n",
    "            saved = True\n",
    "        except Exception:\n",
    "            pass\n",
    "    if not saved and \"dfw\" in globals():\n",
    "        try:\n",
    "            df_stats.save_csv(out_path)\n",
    "            saved = True\n",
    "        except Exception:\n",
    "            pass\n",
    "    if saved:\n",
    "        print(\"Saved CSV to\", out_path)\n",
    "        try:\n",
    "            print(\"CSV sample:\", out_path.read_text().splitlines()[:10])\n",
    "        except Exception:\n",
    "            pass\n",
    "    else:\n",
    "        print(\"Could not save CSV; polars or file-writer not available.\")\n",
    "except Exception as e:\n",
    "    print(\"Saving CSV failed:\", e)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "788e233a",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "### Notes and next steps\n",
    "\n",
    "- If a cell raised an exception because a dependency is missing, install `polars`, `numpy`, and optionally `pillow`.\n",
    "- To run longer scans increase `max_depth` and `threads` in the `probe()` calls.\n",
    "- Use `probe_to_df(..., to_pandas=True)` to get a pandas.DataFrame if you prefer pandas."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "filoma (3.11.11)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
