C++ 14 (g++), 181 171 148 147147 134 bytes
[](auto s){s[0]&=95;int i=1,n=s.length()-1,b;for(;s[i];)s[i++]|=32;b=s[n]s[i++]|=32;b=s[--i]-'y';return s+(b?"y":"")+" Mc"+(b?s:s.substr(0,s[ns[i-1]-'e'?ni:ni-1))+"face";}
Note that clang will not compile this.
Credit goes to Kevin Cruijssen and Olivier GrégoireOlivier Grégoire for the &95
trick.
Thanks to Chris for golfing 11 bytes.
Ungolfed version:
[] (auto s) { // lambda taking an std::string as argument and returning an std::string
s[0] &= 95; // convert the first character to upper case
int n = s.length()-1, // the position of the last character
i = 1, // for iterating over the string
b; // we'll need this later
for(; s[i] ;) // iterate over the rest of the string
s[i++] |= 32; // converting it to lower case
// i is now s.length()
b = s[n]s[--i] - 'y'; // whether the last character is not a 'y'
// i is now s.length()-1
return s + (b ? "y" : "") // append 'y' if not already present
+ " Mc"
+ (b ? s : s.substr(0, s[ns[i-1] - 'e' ? n-1i : ni-1)) // remove one, two, or zero chars from the end depending on b and whether the second to last character is 'e'
+ "face";
}