C++ (gcc), 181 bytes
#include <string>
auto m(auto s){s[0]=s[0]&~32;for(int i=1;s[i];)s[i++]=s[i]|32;int n=s.length()-1,b=s[n]=='y';return s+(b?"":"y")+" Mc"+(b?s.substr(0,s[n-1]=='e'?n-1:n):s)+"face";}
Note that clang will not compile this due to the use of auto
in a function prototype/return type.
Credit goes to Kevin Cruijssen for the &~32
trick.
Try it online here.
Ungolfed version:
#include <string>
auto m(auto s) { // abuse of auto, input and output are std::string
s[0] = s[0] & ~32; // convert the first character to upper case
for(int i=1;s[i];) // iterate over the rest of the string
s[i++] = s[i] | 32; // converting it to lower case
int n=s.length()-1, // the position of the last character
b=s[n]=='y'; // whether or not the last character is a 'y'
return s+(b?"":"y") // append 'y' if not already present
+" Mc"
+(b?s.substr(0,s[n-1]=='e'?n-1:n):s) // remove one, two, or zero chars from the end depending on b and whether the second to last character is 'e'
+"face";
}