#JavaScript (ES6), 194 bytes

Takes input as `([x, y], a)`, where **x** and **y** are the 0-indexed coordinates of the starting position and **a[ ]** is a matrix of characters. The hole is expected to be included in the matrix.

Returns `0` if there's no solution.

<!-- language: lang-js -->

 (p,a)=>(r=F=([x,y],n=0,R=a[y],c=R[x])=>R[c<(R[x]='~')&&[-1,0,1,2].map(d=>(d=(g=_=>(k=a[v=Y,Y+=d%2][h=X,X+=~-d%2])!=0?k:g())(X=x,Y=y))>'o'?0:d>'.'?r=n>r?r:n+1:F(d>'#'?[X,Y]:[h,v],n+1)),x]=c)(p)|r

[Try it online!](https://tio.run/##rVPBbuIwEL3nK2aFFtticEnaw260Q/bUD@AEsqIqTShQaBwlCFFp5V9nHVq1xU5LK9W5zLxnj2fec@6zXdbk9araDktdzA93dOAVZoLGvKZr4mqPjymWNMIJZcqGOU3UPrX8ROV/eBsTM0z0@2oY4ghDjFL5kFW8sBUK4gu6scHant3RDGcDKn5GqVrSFKcDMsM2Ez9olKzjBReCT2mPM3oUYsw0S0ZxMWaSJTWV4zqp43IQxtfcYj2WqCnO0lgtcWfbG4RCoO0kF7wS/@rDxQX8gmZbr9bzJsh12ejNXG70gt/xAECFCL9TBGVjm0kpWe91sRTf4G0ENpItDi4BnYQ5MuARxph3ieOZrxL6G0q9HTxIhQgCK170gXgRQuiL56rmANo4wOl9pd5CpZtmdbuZd/vVcaXvlItoOLvHaeTy41fjdGElPalmwMnlGf6ruVtPO3nbz6dMvEKI3vkDTvUxT8tHwUd77eMGrwIcPxeV1h35ubrdPXQ82zPPKPKGfq7siCztFC72V3rid@1rJ/VMlyB9o8yLWYf/ "JavaScript (Node.js) – Try It Online")